Могу ли я передать аргументы команде псевдонима?

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

например:

alias d="dmesg|grep -iw usb|tail -5" 

Теперь d напечатает последние 5 строк. Если я хочу использовать d для печати другого числа строк, мне придется снова внести изменения в объявление команды псевдонима d.

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

30
задан 10 January 2018 в 11:28

3 ответа

Псевдонимы не принимают аргументов. При использовании псевдонима типа псевдоним foo='bar $1', при запуске псевдонима $1 будет расширен оболочкой до первого аргумента оболочки (что, скорее всего, ничто).

Итак: Используйте функции, вместо этого.

d () {
  num=${1:-5}
  dmesg |grep -iw usb|tail -$num
}

num=${1:-5} использует первый аргумент со значением по умолчанию 5, если он не задан.

Тогда можно сделать:

$ d
# prints 5 lines
$ d 10
# prints 10 lines

Или, если немного изменить используемые опции:

alias d="dmesg|grep -iw usb|tail -n 5"

Тогда можно передать дополнительные опции -n:

$ d
# prints 5 lines
$ d -n 10
# prints 10 lines

Если для tail задано несколько опций -n, то используется только последняя.

27
ответ дан 10 January 2018 в 11:28

Для этого нужна функция, описанная в SO и здесь. Попробуйте следующее:

foo() { /path/to/command "$@" ;}

и вызовите foo с:

foo arg1 arg2 arg3
9
ответ дан 10 January 2018 в 11:28

Обход ограничений псевдонима с помощью групповой команды и здесь-строки

Псевдонимы не могут принимать аргументы, но мы можем "смоделировать" это. Возьмем, к примеру, мой ответ на этот вопрос .

alias mkcd='{ IFS= read -r d && mkdir "$d" && cd "$d"; } <<<'

Ключевые моменты, которые здесь происходят:

  • мы используем read , встроенный для чтения строки в переменную ] d . Поскольку мы хотим прочитать всю строку, включая пустые символы (символы новой строки, табуляции, пробелы), мы используем IFS = и отключаем экранирование обратной косой черты с помощью -r .
  • <<< , который является оператором здесь-строки , позволяет нам перенаправить любую строку, которую мы предоставляем в качестве аргумента, на псевдоним mkcd ; используется mkcd "какой-то каталог"
  • несколько команд в псевдониме объединяются и выполняются в текущей оболочке с использованием {список; } структура (известная как групповая команда в руководстве bash ). Обратите внимание, что начальный пробел после { и ; требуется отдельный список команд.

В вашем конкретном примере мы могли бы сделать:

alias d='{ IFS= read -r n; dmesg | grep -iw "usb" | tail -n ${n:-5};} <<<'

Мы также могли бы использовать разделение слов, чтобы хранить аргументы, разделенные пробелами:

bash-4.3$ { read -r a1 a2; echo "$a1"; echo "$a2";}  <<< "arg1 arg2"
arg1
arg2

Или мы могли бы использовать массивы для предоставления нескольких аргументов:

bash-4.3$ { read -a arr; echo "${arr[1]}"; echo "${arr[0]}";}  <<< "arg1 arg2"
arg2
arg1

Но хороший ли это подход?

Не обязательно. Проблема с таким подходом заключается в том, что он очень специфичен - аргументы не могут быть легко процитированы, что означает, что у нас могут быть только аргументы без пробелов.

bash-4.3$ { read -r a1 a2; echo "$a1"; echo "$a2";}  <<< "'arg1 with space' arg2"
'arg1
with space' arg2

Это, конечно, не то, что широко использовалось бы просто потому, что в реальном мире нам приходится иметь дело со сложными аргументами, поэтому такой подход не совсем практичен. Функции гораздо более гибкие. И необходимость заключать строку args в кавычки быстро раздражает.

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

6
ответ дан 10 January 2018 в 11:28

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

Похожие вопросы: