2015-12-21 3 views
13

Каков наилучший способ определения псевдонима, если, скажем, «ag» выполним?Лучший способ определить «условные» псевдонимы в оболочке

if (($+commands[ag])) ; then alias grep='ag'; fi 

или

[[ -s $(which ag) ]] && alias grep='ag' 

или

if $(which ag >& /dev/null); then alias grep='ag'; fi 

или ...?

К счастью, я имею в виду более надежные, более совершенные и/или более портативные (Bash, Zsh).

Каков ваш совет?

ответ

9

Я не вижу, как простой очевидный вариант POSIX имел бы какие-либо недостатки по сравнению с альтернативами (в основном не переносимыми), которые вы предлагаете.

type ag >/dev/null 2>&1 && alias grep=ag 
+0

Красивый и чистый. В основном отвечаю на мой вопрос. – user3341592

+0

Боковой вопрос: лучше использовать '' 'type ag> &/dev/null''' или просто' '' type ag>/dev/null''' (как вы это делаете)? – user3341592

+1

Первый не переносится. Если вы хотите перенаправить stderr, это '2>/dev/null' или'>/dev/null 2> & 1' для обоих stdout и stderr. – tripleee

1

Я использую эту pathto функции для переносимости всех оболочек Bourne наследия (я не использую which, потому что это не в POSIX поэтому его выходной формат не определен, и он жалуется, когда ничего не найдено, а не молчать):

pathto() { 
     DIRLIST=`echo $PATH|tr : ' '` 
     for e in "[email protected]"; do 
       for d in $DIRLIST; do 
         test -f "$d/$e" -a -x "$d/$e" && echo "$d/$e" 
       done 
     done 
} 

который вторит имя пути для любого исполняемого файла данного, когда нашел, наряду с

test "`pathto less`" != "" && alias more=less 

Что касается производительности, то вы не должны заботиться, потому что количество раз вы называете pathto ничтожно. В ваших первых двух примерах используются не переносные конструкции (()) и [[ ]], и их следует избегать.

Обратите также внимание на то, что я не имею дело с пустыми частями в PATH. Из соображений безопасности их следует избегать, как и ..

+2

Это ненадежно, если любые записи в '$ PATH' содержат пробелы. Но исправление этого в shell-less (и '<(...)' -less) оболочках Bourne потребует некоторой работы (хотя сохранение 'echo' в качестве выходного означает, что вы можете использовать это с обычным трубой и предполагать' printf', что может output ''\ 0'' вы могли бы это сделать ... я думаю). Также это * делает *, в некотором смысле, имеет дело с пустыми значениями $ PATH, поскольку они полностью игнорируют их, поскольку они попадают в цикл 'for d in $ DIRLIST'. Тем не менее, это делает это так, что это означает, что он упустит тот факт, что сама оболочка увидит команду в текущем каталоге. –

+1

Это также использует устаревший аргумент '-a' для' test' и не может использоваться с более чем одной командой, если само имя команды содержит пробел (игнорируя проблему '$ PATH'-with-spaces). (И да, я серьезно сомневаюсь, что это проблема, которая когда-либо появлялась, но полагала, что ее все равно стоит упомянуть.) –

+0

@EtanReisner Ваша педантичность ценится, спасибо! :-) Счастливого Рождества. – Jens

Смежные вопросы