Script ZSH, который требует переменного числа аргументов

Если под «всеми файлами» вы имеете в виду «обычные файлы», а не каталоги, сокеты, FIFO и т. Д., То вам нужно будет найти те, которые используют, ну, find :

find "$dir" -maxdepth 1 -type f

и передайте их xargs , чтобы вызвать на них head :

find "$dir" -maxdepth 1 -type f -print0 | xargs -0 head -n 4

Если вы также хотите следовать символическим ссылкам, которые в конечном итоге указывают на обычные файлы, используйте - xtype вместо -type (или используйте find -L вместо find ).

(Я предполагал, что GNU find и xargs выше; если вы не работаете в среде GNU, см. Примечания в комментариях).

3
05.09.2018, 15:46
2 ответа

Так как я на самом деле не zshпользователь, я напишу shрешение,(zshкоторое должно выполнить и его ).

Суть в том, чтобы создать список с одним битом ssh -t hostnameдля каждой опции командной строки, кроме последней, а затем выполнить этот список как команду.

#!/bin/sh

argn=$#
i=0

for arg do
   shift
   i=$(( i + 1 ))

   if [ "$i" -lt "$argn" ]; then
       set -- "$@" ssh -t "$arg"
   else
       set -- "$@" "/pathtofile/$arg/log.log"
   fi
done

command "$@"

Запуск как

sh script.sh alpha beta gamma zeta

будет создан список

ssh -t alpha ssh -t beta ssh -t gamma /pathtofile/zeta/log.log

Последняя команда в сценарии будет выполнять это как команду.

Список встроен в $@, список позиционных параметров, который при старте скрипта содержит параметры командной строки скрипта. Цикл отслеживает, когда встречается последний элемент этого исходного списка, и обрабатывает его особым образом.

Команда setпри использовании, как указано выше, добавит к списку, а shiftудалит первый элемент списка, (тот, который мы сейчас обрабатываем ).

Я уверен, что это можно было бы сделать короче и элегантнее сzsh-специальным синтаксисом.

2
27.01.2020, 21:18

Я не думаю, что вы легко отделаетесь без петли:

cmd=()
for i ($argv[1,-2]) cmd+=(ssh -t $i)
$cmd tailf /pathtofile/$argv[-1]/log.log

Строго говоря, поскольку это командная строка оболочки, которую вы передаете в ssh, если вы хотите иметь возможность поддерживать произвольные значения для этих $1, $2, вам нужно заключить эти аргументы в кавычки и добавить дополнительный уровень цитирования для каждого ssh.

Здесь предполагается, что оболочка входа пользователя на всех хостах — Bourne -, например:

cmd=(tailf /pathtofile/$argv[-1]/log.log)
argv[-1]=()
while (($#argv)) {
  cmd=(ssh -t "$argv[-1]" ${(j: :)${(qq)cmd}})
  argv[-1]=()
}

Это должно заставить его работать при вызове как

that-script host1 host2 'dir with spaces and other nasty characters'
2
27.01.2020, 21:18

Теги

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