Назначение команды переменной без псевдонима

Я просто случайно узнал, что в bash мы можем назначить команду в переменную без использования alias .

 g=date $g Mon Jun 27 13:00:40 MYT 2016 

Это работает. Вот еще один пример:

 jj="ping yahoo.com" $jj PING yahoo.com (98.138.253.109) 56(84) bytes of data. 64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=1 ttl=41 time=347 ms 64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=2 ttl=41 time=345 ms 64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=3 ttl=41 time=345 ms 

Я использую эту версию bash bash --version GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

Я просмотрел stackexchange и tldp abs , но не нашел, что мы можем сделать это как это. Так это новые черты bash или чего-то не замечаемого? Рассматривается ли это замена команды ?

  • Переменная от конкатенации переменных
  • 4 Solutions collect form web for “Назначение команды переменной без псевдонима”

    Это ожидаемое поведение и работает целую вечность. Это полезно для создания команд в скриптах.

    Скажем, например, что я иногда должен применять декомпрессию на некотором входе перед отправкой в ​​конвейер (и сжатие на выходе впоследствии), но иногда нет. Использование bash :

     if (( use_compression == 1 )); then infilter='gzip -d -c' outfilter='gzip -c' else infilter='cat' outfilter='cat' fi $infilter "$indatafile" | somepipeline | $outfilter >"$outdatafile" в if (( use_compression == 1 )); then infilter='gzip -d -c' outfilter='gzip -c' else infilter='cat' outfilter='cat' fi $infilter "$indatafile" | somepipeline | $outfilter >"$outdatafile" 

    Это замена команды? Нет. «Подстановка команд» относится конкретно к замене $(...) или обратного тика на содержимое его вывода.

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

    Это означает, что в командной строке также работают такие вещи, как следующие:

     $ decompress='gzip -d -c' $ ${decompress/g/gun/} filename >unzippedfilename 

    (что будет выполнять gunzip а не gzip )

    EDIT : О псевдонимах.

    В руководстве bash говорится:

    Для почти всех целей псевдонимы заменяются функциями оболочки.

    … и я согласен.

    Псевдонимы хороши для коротких вещей, таких как

     alias ls="ls -F" 

    (это единственный псевдоним, который у меня есть в моих собственных сеансах оболочки)

    Вероятно, вы не хотите использовать расширения параметров для команд «aliasing» в командной строке. Если не по какой-либо другой причине, чем боль в области шеи. Расширение параметров также не позволяет выполнять несколько более сложные задачи, такие как конвейерная обработка.

    Если вы выполняете умеренно сложные операции, которые вы выполняете регулярно, вместо этого используйте вместо них функции оболочки.

    Взяв пример из принятого ответа на вопрос U & L (на который вы ссылаетесь в комментариях ниже):

     alias my_File='ls -f | grep -v /' 

    Этот псевдоним, очевидно, работает, но

     my_File='ls -f | grep -v /' 

    не будет работать, если вы затем попытаетесь использовать $my_File в качестве команды в командной строке (как объясняется, почему в этом потоке U & L).

    С помощью функции оболочки вы также сможете делать такие вещи, как аргументы pass:

     function my_File { ls -l "$@" | fgrep -v '/' } $ my_File -iF symlink 84416642 lrwxr-xr-x 1 kk staff 4 Jun 27 09:03 symlink@ -> file 

    При интерактивном использовании оболочка считывает строки ввода с терминала. После ввода строки она анализируется путем разбиения на токены (слова и операторы). Значки или слова затем расширяются или разрешаются в определенном порядке.

    Примечание. Обычно лучше всего ссылаться на канонический источник информации, такой как проектная документация или отраслевая спецификация, из вторых источников, таких как Advanced Bash-Scripting Guide, онлайн-учебники, книги или даже Stack Exchange :). Такие вторичные источники полезны для введения и объяснения понятий на более простом языке, но обычно они не предназначены для заполнения или замены официальной документации. Информация из вторичного источника также может быть устаревшей.

    В этом случае в спецификации POSIX для разбора Simple Commands указано, что

    1. Слова, которые не являются переменными назначениями или перенаправлениями, должны быть расширены. Если после их расширения остаются какие-либо поля, первое поле считается именем команды, а остальные поля являются аргументами для команды.

    В разделе руководства Bash по Simple Command Expansion также указано, что

    1. Слова, которые не являются переменными назначениями или перенаправлением, расширяются (см. Раздел «Расширения оболочки»). Если после расширения слова остаются какие-либо слова, первое слово считается именем команды, а остальные слова являются аргументами.

    Это не подстановка команд, это замена переменных . Вы не назначаете команду в переменную, вы назначаете строку. Команда запускается, когда вы используете переменную, а не во время назначения.

    g=date хранит g=date строки в переменной g . Если вы затем запустите echo "$g" , это напечатает значение g , то есть date (за которым следует новая строка), потому что значение g передается команде echo в качестве первого аргумента. Если вы запустите "$g" , это помещает date строки в первую позицию команды, поэтому это имя команды.

    При $jj вступает в игру второй фактор. Поскольку расширение переменной вне кавычек, к значению применяется оператор split + glob . В этом случае это означает, что значение jj разбивается на два слова, разделенные пробелом. Таким образом, слово ping заканчивается в командном положении, и слово yahoo.com является первым аргументом.

    Он просто использует переменные оболочки, концепцию, которая существовала и работала вот так на протяжении десятилетий (без преувеличения).

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

    Linux и Unix - лучшая ОС в мире.