Основное различие между псевдонимами и функциями - то, что псевдонимы не берут аргументы ¹, но функции делают. Когда Вы пишете что-то как alias l='ls --color'
, l foo
расширен до ls --color foo
; Вы не можете захватить foo
в расширение псевдонима и делают что-то другое с ним способ, которым можно сделать с функцией. См. также, Как передать параметр для искажения?.
Псевдонимы ищутся перед функциями: если у Вас есть и функция и названный псевдоним foo
, foo
вызывает псевдоним. (Если псевдоним foo
расширяется, это временно заблокировано, который делает вещи как alias ls='ls --color'
работа. Кроме того, можно обойти псевдоним в любое время путем выполнения \foo
.) Я не ожидал бы видеть измеримое различие в производительности все же.
Функции и автономные сценарии имеют главным образом подобные возможности; вот несколько различий, о которых я могу думать:
Что-то это является промежуточным между функцией и автономным сценарием, является отрывком сценария, который Вы читаете с source
или .
встроенный. Как функция, это может изменить среду оболочки и должно быть записано на языке оболочки. Как сценарий, это загружается каждый раз, когда это вызывается и только.
¹ Да, я знаю, это не относится к tcsh.
Возможное решение: спецификация POSIX для ls
указывает -i
, таким образом, возможно, это портативно. Делает любой знает о популярной реализации ls
который не поддерживает это или печатает его по-другому от следующего примера:
$ ls -di /
2 /
Это должно быть портативно и работать с именами файлов, содержащими пробелы, новые строки или другое нечетное продвижение символов к известно капризному ls поведению.
filename="whatever file name"
find . -name "$filename" -exec sh -c 'ls -di "$0" | head -1' {} \;
Для увеличения мобильности, можно также реализовать определенную для платформы функцию обертки (здесь названный statinode()
) вокруг stat
команда, которая может быть основана на выводе uname -s
(см. uname).
ls
был бы необходим как опция нейтрализации только.
(
shopt -s nocasematch nullglob # using Bash
case "$(uname -s)" in
# nocasematch alternative
#[Ll][Ii][Ni][Uu][Xx] ) statinode() { stat -c '%i' "$@"; return 0; };;
"Linux" ) statinode() { stat -c '%i' "$@"; return 0; };;
"Darwin" ) statinode() { stat -f '%i' "$@"; return 0; };;
"FreeBSD" ) statinode() { stat -f '%i' "$@"; return 0; };;
* ) statinode() { ls -id "$@" | cut -d ' ' -f 1; return 0; };;
esac
#export -f statinode
statinode / / / /
shopt -u nocasematch nullglob
)
Другое решение:
#!/usr/bin/perl
use strict;
use warnings;
die "Usage: $0 filename\n" if scalar @ARGV != 1;
my $file = $ARGV[0];
my @stat = stat $file;
die "$file: $!\n" if not @stat;
print "$stat[1]\n";
Можно, вероятно, безопасно предположить, что Perl установлен.
stat
часть пакета Coreutils GNU. OSX использует другое stat
реализация (по-видимому, основанная на BSD), который не берет те же параметры командной строки.
Вы могли всегда устанавливать GNU Coreutils на OSX. Конечно, это не помогает при необходимости в решении, которое работает над системами OSX, которые не имеют GNU Coreutils.
Или, если я читаю статистику OSX (1) страница справочника правильно, stat -f %i file
на OSX ведет себя как stat -c %i file
использование версии Coreutils. (Определение, который версия stat
Вы имеете, другой вопрос; Вы могли попробовать stat --version >/dev/null
; если это успешно выполняется, у Вас есть версия Coreutils GNU.)
ls -di
решение является более портативным и меньше проблемы, но это - альтернатива.
Подобный подходу jeff, stat
мог быть протестирован непосредственно также.
(
if (stat -c '%i' / 1>/dev/null 2>&1; exit $?); then
statinode() { stat -c '%i' "$@"; return 0; }
elif (stat -f '%i' / 1>/dev/null 2>&1; exit $?); then
statinode() { stat -f '%i' "$@"; return 0; }
elif test -n "$(exec 2>/dev/null; ls -id / | cut -d ' ' -f 1)"; then
statinode() { ls -id "$@" | cut -d ' ' -f 1; return 0; }
else
echo 'Could not create statinode(). Exiting ...' && exit 1
fi
# export -f statinode
statinode / / / /
declare -f statinode
)
stat
команда не работала над OS X,ls -di
работавший на обоих. – l0b0 08.11.2011, 16:54ls
имеет-d
и-i
как обязательные функции (хотяls
самостоятельно является дополнительным, как все остальное). – Gilles 'SO- stop being evil' 09.11.2011, 02:00ls
с-i
передние клавиатуры с пробелами, по крайней мере, на Солярисе 10 (возможно Солярис 11, я не проверил). Похоже, что это было традиционным поведением, возвращающимся к версии 7 Unix, таким образом, я подозреваю, что много корпоративных *отклоняет разновидности, сохраненные этим поведением (у меня только есть Солярис 10 под рукой хотя). Столь рядом, как я могу сказать, если Вы используете что-то, что правильно формирует рисунок полей в произвольном пробеле (так, нетcut
, но напримерawk
или просто собственное разделение поля оболочки), это портативно, чтобы ожидать, что первая непробельная строка будет inode числом. – mtraceur 09.10.2016, 08:30