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


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

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

foo*

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

5 52

5 ответов:

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

$ # quote it
$ foo '*'

$ # or escape it
$ foo \*

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

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

для снарядов sh, bash и ksh:

alias foo='set -f;foo';foo(){ command foo "$@";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 "$@";set +f;}

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

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

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

alias foo='noglob ~/bin/foo'

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

обновление:

пользователей geira указал, что в случае с bash shell

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}

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

reset_expansion(){ CMD="";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'

что исключает потребность для функции foo.

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

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

   set -o noglob

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

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

foo "*"

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

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

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

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