bash函数prepend_line
具有两个参数:字符串和文件的全限定路径。用于记录日志,在日志文件的顶部插入当前日期/时间和字符串。
独立使用效果很好:prepend_line "test string" "$log_file"
如何从命令获取输出,例如mv -fv "$fileOne" "$fileTwo"
用作prepend_line
的第一个参数?
我已经尝试过各种组合到xargs
的管道,但是我不知道它是如何工作的,我也不相信这是在任何情况下的最佳方法。
答案 0 :(得分:1)
如果您确实需要:
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
内部,我将输出重定向到日志文件或某些临时文件,从而避免了解析和极端情况的需要。