Передать вывод из команды в другую команду - PullRequest
0 голосов
/ 26 июня 2019

Функция bash, prepend_line, принимает два параметра: строку и полный путь к файлу.Он используется для регистрации, вставки текущей даты / времени и строки в верхней части файла журнала.

Автономное использование отлично работает: prepend_line "test string" "$log_file"

Как я могу получить вывод изкоманда, например mv -fv "$fileOne" "$fileTwo", которая будет использоваться в качестве первого параметра для prepend_line?

Я пробовал различные комбинации трубопровода до xargs, но я не понимаю, как это работает, и яне уверен, что это лучший способ в любом случае.

1 Ответ

1 голос
/ 26 июня 2019

Если вам действительно нужно:

export -f prepend_line
mv -fv "$fileOne" "$fileTwo" |
xargs -0 bash -c 'prepend_line "$1" "$log_file"' --

-0 анализирует строку как делимеризуемую нулем. Поскольку в выводе mv -v не должно быть нулей, поскольку имена файлов не могут иметь нулевой байт, вы получите только один элемент. Этот элемент / строка будет передан в качестве первого аргумента для подоболочки bash.

Проверено с:

prepend_line() {
  printf "%s\n" "$@" | xxd -p
}

fileOne=$'1\x01\x02\x031234566\n\t\e'
fileTwo=$'2\x01\x02\x031234566\n\t\e \n\n\n'
export -f prepend_line

printf "%s\n" "$fileOne -> $fileTwo" |
xargs -0 bash -c 'prepend_line "$1" "$log_file"' --

Скрипт выведет (вывод из xxd -p внутри prepend_line):

31010203313233343536360a091b202d3e2032010203313233343536360a
091b200a0a0a0a0a0a

Тот же вывод в шестнадцатеричном виде с некоторыми дополнительными символами новой строки и комментариями:

# first filename $'1\x01\x02\x031234566\n\t\e'
31010203313233343536360a091b
# the string: space + '->' + space
202d3e20
# second filename $'2\x01\x02\x031234566\n\t\e \n\n\n'
32010203313233343536360a091b200a0a0a0a0a0a

Если вам действительно нужно проанализировать некоторые странные входные данные, вы можете преобразовать свою строку в шестнадцатеричное с помощью xxd -p. Затем, позже, преобразуйте его обратно в машинное представление с помощью xxd -r -p и передайте прямо в вывод:

prepend_line() {
    # some work

    # append the output of the "$1" command to the log_file
    <<<"$1" xxd -p -r >> "$2"

    # some other work
}

prepend_line "$(mv -fv "$fileOne" "$fileTwo" | xxd -p)" "$log_file"

Но я сомневаюсь, что вам когда-нибудь понадобится разобраться с такими случаями. Кто называет имена файлов с помощью $'\x01' и суффиксы с пустыми символами новой строки 'great_script.sh'$'\n\n'?

Во всяком случае, объективно я бы предпочел, чтобы интерфейс использовал поток:

 mv -fv "$fileOne" "$fileTwo" | prepend_line "$log_file"

Для правильного распространения ошибок требуется set -o pipefail. Внутри prepend_line я бы просто перенаправил вывод в файл журнала или какой-нибудь временный файл, избавив от необходимости разбора и угловых случаев.

...