Почему расширение переменных внутри псевдонима работает «как задумано» только в одном из этих случаев? - PullRequest
4 голосов
/ 05 января 2012

Этот вопрос частично был вдохновлен этим .

alias foo='ls -1 $1'
foo /etc

отображает содержимое / etc, по одному элементу в строке.

ls -1 /etc | tail

отображаетпоследние десять элементов в /etc.

Но

alias foo='ls -1 $1 | tail'
foo /etc

отображает: tail: ошибка чтения `/ etc ': каталог

Ответы [ 3 ]

8 голосов
/ 05 января 2012

Я обнаружил, что расширение псевдонимов в псевдонимах некорректно и не рекомендуется:http://www.gnu.org/software/bash/manual/bashref.html#Aliases

Используйте функцию вместо: function foo() { ls -1 $1; }

2 голосов
/ 05 января 2012

Псевдонимы, сделанные таким образом, будут расширяться только из набора параметров:

$ alias foo='ls -1 $1 | tail'
$ foo .
# Type Esc-C-e: this expands aliases/globs/environment variables...
# ... And the result of the expansion is:
$ ls -1  | tail .
# $1 has disappeared
$ set bar  # set $1...
$ foo . # again, Esc-C-e
$ ls -1 bar | tail .
1 голос
/ 18 января 2017

Прямой ответ на ваш вопрос: удача, что первый случай соответствует тому, что вы ожидаете.

Вы написали свои псевдонимы, предполагая, что $ 1 будет представлять первый «аргумент» для вашего псевдонима. На самом деле, псевдонимы в bash не принимают аргументы, они просто заменяют текст псевдонима содержимым в кавычках, которые вы ему присвоили. Так что же на самом деле делают ваши 1 доллар?

Отдельно от псевдонимов, в bash, $0 распространяется на первое, что вводится как сценарий или оболочка, в которой вы находитесь (команда). $1 - первый аргумент (или второй набранный предмет). Поскольку вы вводите командную строку в командной строке, скорее всего, ваша оболочка была запущена терминалом или оконным менеджером, который запускал команду bash без аргументов.

Попробуйте это из командной строки:

$ echo $0
bash
$ echo $1
# prints nothing

Итак, в вашем первом случае, <strong>foo</strong> /etc расширяет Foo, чтобы получить <strong>ls -1 $1</strong> /etc и поскольку $ 1 равен нулю,

<strong>ls -1</strong> /etc

также, если вы добавите | tail к конвейеру, он будет работать нормально.

В вашем втором случае <strong>foo</strong> /etc расширяет Foo, чтобы получить <strong>ls -1 $1 | tail</strong> /etc и так как $ 1 равен нулю,

<strong>ls -1 | tail</strong> /etc

, которая выдает эту ошибку, которую вы получили, потому что команда после канала содержит ошибку: tail не может работать с каталогом /etc

...