Остановить расширение символа подстановки оболочки?

Есть ли способ для скомпилированной программы командной строки сказать bash или csh, что он не хочет, чтобы в его параметрах были расширены какие-либо символы подстановки?

Например, может потребоваться команда оболочки, например:

foo *

просто вернуть числовое значение ASCII этого символа.

Ответ 1

Нет. Расширение происходит до того, как команда действительно будет запущена.
Вы можете отключить глобус только перед запуском команды или указав звездочку.

$ # quote it
$ foo '*'

$ # or escape it
$ foo \*

$ # or disable the glob (noglob)
$ set -f
$ foo *

$ # alternative to set -f
$ set -o noglob
$ # undo it by 
$ set +o noglob

Ответ 2

Хотя верно, что сама команда не может отключить глобус, пользователь может сказать оболочке Unix, чтобы не глотать определенную команду. Обычно это делается путем редактирования файлов конфигурации оболочки. Предполагая, что команда foo может быть найдена вдоль пути к команде, в соответствующий файл конфигурации необходимо добавить следующее:

Для оболочек sh, bash и ksh:

alias foo='set -f;foo';foo(){ command foo "[email protected]";set +f;}

Для оболочек csh и tcsh:

alias foo 'set noglob;\foo \!*;unset noglob'

Для оболочки zsh:

alias foo='noglob foo'

Путь команд не обязательно должен использоваться. Скажем, команда foo хранится в каталоге ~/bin, а выше:

Для оболочек sh, bash и ksh:

alias foo='set -f;foo';foo(){ ~/bin/foo "[email protected]";set +f;}

Для оболочек csh и tcsh:

alias foo 'set noglob;$home/bin/foo \!*;unset noglob'

Для оболочки zsh:

alias foo='noglob ~/bin/foo'

Все вышеперечисленное было протестировано с использованием Apple OSX 10.9.2. Примечание. При копировании вышеуказанного кода будьте осторожны при удалении любых пробелов. Они могут быть значительными.

Обновление:

Пользователь geira указал, что в случае оболочки bash

alias foo='set -f;foo';foo(){ ~/bin/foo "[email protected]";set +f;}

можно заменить на

reset_expansion(){ CMD="$1";shift;$CMD "[email protected]";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'

что устраняет необходимость в функции foo.

Некоторые веб-сайты, используемые для создания этого документа:

Ответ 3

Расширение выполняется оболочкой до запуска вашей программы. Ваша программа не имеет ни малейшего представления о том, произошло ли расширение или нет.

   set -o noglob

отключит расширение в вызывающей оболочке, но вам придется это сделать перед тем, как вызывать свою программу.

Альтернативой является процитировать ваши аргументы, например,

foo "*"

Ответ 4

Остерегайтесь: если нет имен, соответствующих маске, bash передает аргумент as-is без расширения!

Доказательство (pa.py - очень простой script, который просто печатает свои аргументы):

 $ ls
f1.cc  f2.cc  pa.py
 $ ./pa.py *.cc
['./pa.py', 'f1.cc', 'f2.cc']
 $ ./pa.py *.cpp
['./pa.py', '*.cpp']

Ответ 5

Нет. Оболочка Bourne всегда выполняет globbing, когда это необходимо, перед выполнением команды. Пользователь должен указывать или избегать аргументов, чтобы предотвратить зависание, например foo \*; фактическая выполняемая программа не может указывать предпочтения.