将bash命令拆分为几个可重用的部分
如何将使用管道的命令拆分为不同的部分 我有以下正在工作的bash命令:将bash命令拆分为几个可重用的部分,bash,find,Bash,Find,如何将使用管道的命令拆分为不同的部分 我有以下正在工作的bash命令: RESULT=$(find "/path/to/releases" -maxdepth 0 -type d -print0 | xargs -r -0 ls -1 -t | tail -n 1) 我宁愿将管道拆分为多个变量,这样我就可以在其他地方重用RESULT1或RESULT2: RESULT1=$(find "/path/to/releases" -maxdepth 0 -type d -print0) if [ -
RESULT=$(find "/path/to/releases" -maxdepth 0 -type d -print0 | xargs -r -0 ls -1 -t | tail -n 1)
我宁愿将管道拆分为多个变量,这样我就可以在其他地方重用RESULT1或RESULT2:
RESULT1=$(find "/path/to/releases" -maxdepth 0 -type d -print0)
if [ -n ${RESULT1} ]; then
RESULT2=${RESULT1} | xargs -r -0 ls -1 -t
RESULT3=${RESULT2} | tail -n 1
]
这可能吗
更新:我还想拆分东西的原因是,我想先检查第一部分是否确实找到了东西,然后再继续下一个管道
更新2:像这样解决它;使用上面的一些例子来更容易地解释我的问题。这是实际的代码
DEPLOY_PATH="/data/www"
KEEP_RELEASES=3
function cleanup() {
RELEASES=()
OLDEST_RELEASE=
for item in "${DEPLOY_PATH}"/releases/* ; do
[[ -L ${item} || ! -d ${item} ]] && continue
[[ -z ${OLDEST_RELEASE} || ${item} -ot ${OLDEST_RELEASE} ]] && OLDEST_RELEASE=${item}
RELEASES+=("${item}")
done
if [ "${#RELEASES[@]}" -gt 0 ] && [ "${#RELEASES[@]}" -gt "${KEEP_RELEASES}" ]; then
rm -rf "${DEPLOY_PATH}"/releases/$(basename "${OLDEST_RELEASE}")
cleanup
fi
}
糟糕的是,像xargs这样的find和pipes链接并不总是最好的选择。在我看来,当使用常规bash数组时,它会使我的脚本变大。是的,有可能:
RESULT1=$find/path/to/releases-maxdepth 0-type d
结果2=$echo$RESULT1 | xargs-rls-1-t
结果3=$echo$RESULT2 | tail-n1
在可重用性方面,我们最好采取类似的方法:
find_release(){
find "/path/to/releases" -maxdepth 0 -type d -print0
}
list_by_time(){
xargs -r -0 ls -1 -t
}
tail_1(){
tail -n 1
}
# Then you can do :
find_release | list_by_time | tail_1
find的输出是一个空分隔字符串,但是shell变量以空结尾;RESULT1将只有find输出的第一个文件。在这种情况下,您不需要find:files=/path/to/releases/*/并且一旦文件位于一个数组中,使用for循环迭代比使用xargs更容易。非常感谢。然而,我确实得到了一个警告命令替换:在输入中忽略空字节。有没有机会也压制或解决这个问题?这对给定的情况不起作用;RESULT1无法存储多个以null结尾的文件名。谢谢@chepner,我已经编辑了答案以删除-print0和-0,它现在应该可以工作了。现在它不适用于名称中包含空格的文件。使用-print0是有原因的。谢谢Philippe,但使用这种方法,在继续下一个管道之前,我无法检查find_版本是否确实包含某些内容。