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

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

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

фу *

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

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'

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

Обновить:

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

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

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

reset_expansion(){ CMD="$1";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 \*; выполняемая программа не может указывать предпочтения.

Другие вопросы по тегам