У меня две проблемы. Я пытаюсь передать файлы через канал в качестве аргумента, и я пытаюсь использовать этот файл как переменную внутри функции sh
.
Вот моя команда:
find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh
Здесь моя строка находит все файлы, которые выглядят как " segment.something
" и передает их в правую часть конвейера. В someFunction.sh
, мне нужно имя файла в качестве аргумента. Допустим, файл вводится в segment1
.
Например, будет someFunction.sh
распечатана каждая строка .segment1
Как передать вывод из левой части канала в правую часть, а затем как вызвать его внутри someFunction.sh
?
решение1
Ваша команда
$ find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh
приводит к тому, что максимум четыре копии скрипта someFunction.sh
оболочки будут запущены ( -P 4
) параллельно (новые будут созданы сразу после завершения старых), каждая из которых получает одно имя файла в качестве аргумента ( -n 1
).
Это означает, что каждый вызов вашего скрипта будет выглядеть так:
sh someFunction.sh segmentsomething
Внутри скрипта оболочка поместит значенияпозиционные параметры(аргументы в командной строке) в $1
и $2
т. д. ( $0
обычно содержит имя самого скрипта). В вашем случае $1
будет содержать имя файла, а остальные будут пустыми.
Итак, в сценарии:
filename="$1"
echo "$filename"
cat "$filename"
Вот и все. Теперь, обычно, когда кто-то ищет find
файлы и передает их имена, xargs
возникает проблема с неудобными именами файлов, о которых люди склонны напоминать друг другу, и я сделаю это здесь тоже.
Утилита find
передает имена файлов, разделенные пробелами. Это нехорошо, если у вас есть имена файлов с пробелами, так как это может вызвать проблемы при xargs
вызове вашего скрипта с правильными именами.
Поэтому хорошей практикой являетсявсегдаиспользуйте -print0
with find
и -0
with xargs
, что означает, что имена файлов разделяются не пробелами, а nul
символами ( \0
). Это делает его намного безопаснее.
Таким образом:
$ find . -name 'segment*' -print0 | xargs -0 -n1 -P4 sh someFunction.sh
решение2
Вы можете использовать что-то подобное, предполагая, что someFunction.sh
оно находится в вашем рабочем каталоге.
find . -name 'segment*' -print0| xargs -0 -n1 -P4 ./someFunction.sh
И позволяют файлы с пробелами в имени (Распространенная проблема). В моем случае у -print0
меня есть-0
someFunction.sh
#!/bin/bash
echo "Arg: " $1
cat $1
Который просто выводит имя файла, а затем записывает содержимое переданного файлаsomeFunction.sh