xargs не использует мой псевдоним «ls»

8

В AIX (но это происходит и в HP-UX), у меня есть GNU ls на моем пути, и он также называется псевдонимом ls.

Когда я использую xargs, вместо псевдонима он использует стандартный Unix ls.

Например ( flocateэто функция, которая находит точный путь к предмету поиска):

flocate mirrorvg | xargs ls -lh
ls: illegal option -- h
usage: ls [-1ACFHLNRSabcdefgiklmnopqrstuxEUX] [File...]

ls -lh /usr/sbin/mirrorvg
-r-xr-x--- 1 root system 37K apr  3  2014 /usr/sbin/mirrorvg*

Почему xargs не использует lsпсевдоним?

elbarna
источник
1
Что именно означает «у меня GNU ls на моем пути»? Является ли каталог, содержащий lsисполняемый файл GNU, $PATHпеременной вашей среды, и предшествует ли он каталогу (возможно /bin), содержащему не-GNU lsкоманду? Пожалуйста, обновите ваш вопрос, чтобы показать нам фактическую ценность вашего $PATH. xargsвыполнит первую ls команду, найденную в каталоге вашего каталога $PATH; он не знает об псевдонимах.
Кит Томпсон,

Ответы:

9

Команда xargsможет запускать только команды, но не псевдонимы. Параллельно GNU, однако, может запускать функции:

The command must be an executable, a script, a composed
command, or a function. If it is a function you need to export
-f the function first. An alias will, however, not work (see
why http://www.perlmonks.org/index.pl?node_id=484296).

Поэтому я бы порекомендовал либо:

  • Предоставляя xargs полный путь к версии ls, которую вы хотите использовать (или однозначное имя, возможно, в glsзависимости от того, как оно было установлено в вашей системе) или, если ваша оболочка это позволяет,

  • Определение lsкак функция ( function ls { gls "$@"; }; export -f lsв bash) и использование GNU параллельно вместо xargs ( parallel -j1если вы хотите использовать один процессор).

dhag
источник
Функции экспорта работают только с bashоболочкой. Вы также можете использовать xargsс экспортированными функциями: ls() { gls "$@"; }; export -f ls; ... | xargs bash -c '"$0" "$@"' ls
Стефан Шазелас
О, хороший трюк, это может быть полезно, если кто-то вынужден использовать xargs.
дхаг
Вы можете использовать, env_parallelесли вы хотите использовать псевдонимы или не хотите экспортировать функцию. Псевдонимы поддерживаются в: ash, bash, csh, dash, fish, ksh, mksh, pdksh, tcsh, zsh. Поддерживаются функции: bash, fish, ksh, mksh, pdksh, sh, zsh. Они даже работают, если вы запускаете команды на удаленных серверах. gnu.org/software/parallel/env_parallel.html
Оле Танге,
3

Замена псевдонима выполняется оболочкой. Если оболочка пытается вызвать команду foo, и есть псевдоним foo=bar, это оболочка , которая подменяет fooна barздесь.

Оболочка делает это только для команд. (В противном случае аргументы, которые совпадают с командами с псевдонимами, также будут заменены.) Но lsздесь вы используете не оболочку, а аргумент xargs. Поэтому оболочка не заменяет его.

Затем xargsвыполняется ls, но он не знает об псевдонимах, поэтому он просто запускает первый из найденных в пути.

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

Мэринус
источник
1
Обратите внимание, что выполнение alias xargs='xargs 'скажет оболочке расширять псевдонимы после xargs.
Стефан Шазелас