2016-12-08 10 views
3

Я пытаюсь написать сценарий, который использует find и xargs для архивирования старых файлов в большой папке. Вот строка:xargs sh -c пропустить первый аргумент

find /tmp/messages/ -mtime +9 -print0 | xargs -x -t -0 -n 1000 sh -c 'tar rPf /tmp/backup.tar "[email protected]" && rm -f "[email protected]"; sleep 1 && echo Finished one loop: $(date +"%T")' 

Сценарий в основном работает, но он пропускает первый файл каждый раз, когда команды запуска 1000 файлов, и я не могу понять, почему.

Вот еще один пример (я пытался играть с более простых команд, чтобы увидеть, что происходит:

Если я просто использовать эхо и xargs, я могу запустить одну команду эффективно:

$ echo a b c d e f| xargs -n 2 echo "[email protected]" 
a b 
c d 
e f 
$ echo a b c d e f| xargs -n 3 echo "[email protected]" 
a b c 
d e f 

С другой рука, если я хочу спать каждый раз, когда я печатаю каждый набор, добавить Sh -c, чтобы добавить строку команд:?

$ echo a b c d e f| xargs -n 2 sh -c 'echo "[email protected]"; sleep 1;' 
b 
d 
f 
$ echo a b c d e f| xargs -n 3 sh -c 'echo "[email protected]"; sleep 1;' 
b c 
e f 

посмотреть, как пропустил первый пункт

Любые идеи о том, что может происходить здесь?

Заранее благодарен! И дайте мне знать, если вам нужна дополнительная информация, я был бы рад предоставить ее.

+1

Посмотрите на опцию '-c', https://linux.die.net/man/1/bash – Inian

ответ

3

Первый аргумент sh -c или bash -c это имя скрипта, т.е. $0, не напечатанного при использовании [email protected]:

Примеры:

echo a b c d e f| xargs -n 3 bash -c 'echo "$0 [email protected]"' 
a b c 
d e f 

Чтобы исправить это, вы можете передать _ в качестве фиктивного имени сценария, а затем он должен работать:

echo a b c d e f| xargs -n 3 bash -c 'echo "[email protected]"' _ 
a b c 
d e f 

Будет хорошо работать e аже с sleep например:

echo a b c d e f| xargs -n 3 bash -c 'echo "[email protected]"; sleep 1' _ 
a b c 
d e f 
+1

Да, это похоже на трюк, спасибо за помощь! –

1

В языке командной оболочки @special parameter

Заменяется позиционными параметрами, начиная с первого.

Команда sh вызывается в следующем виде:

sh -c[OPTIONS] command_string [command_name [argument...]] 

Из документации для опции -c:

чтения команд из command_string операнда. Задайте значение специального параметра 0 (см. Специальные параметры) из значения операнда command_name и позиционных параметров ($1, $2 и т. Д.) В последовательности из оставшихся операндов аргументов.

Например, в следующей команде:

sh -c 'tar czvf arch.tar.gz [email protected]' a b c 
  • command_string является 'tar czvf arch.tar.gz [email protected]',
  • command_name является a,
  • первым argument является b
  • второй argument является c

Таким образом, в команде строка $0 будет расширяться a, $1 к b, $2 на c и [email protected] специальный параметр будет расширяться b c.

Поэтому, если вы хотите использовать command_name в командной строке, обратитесь к нулевому значению параметра, то есть $0.