我运行以下bash命令来格式化带有文件inode和哈希的日志:
time find BASE_DIR -maxdepth 1 -mindepth 1 -type d |
sort |
xargs -P100 -n1 -IFF bash -ce "find FF -type f" |
sort |
xargs -n1 -I {} bash -ce "
FILE=$1; INODE=`stat -c '%i' $FILE`;
HASH=`cat $FILE | md5sum | cut -d' ' -f1`;
printf 'Name: %s - Inode: 0x%X - MD5: %s\n' $FILE $INODE $HASH;" {}
但是,每次运行此命令,我都会得到类似的东西:
Name: FILE1 - Inode: 0xFFFFFFFFFFFFFFFF> - MD5: SOME_MD5
Name: FILE1 - Inode: 0xFFFFFFFFFFFFFFFF> - MD5: SOME_MD5
Name: FILE1 - Inode: 0xFFFFFFFFFFFFFFFF> - MD5: SOME_MD5
Name: FILE1 - Inode: 0xFFFFFFFFFFFFFFFF> - MD5: SOME_MD5
每次都相同的文件。如何正确将args传递给bash?
编辑
通过将第二个xargs更改为:
xargs -n1 bash -ce '
path="$0";
inode=`stat -c "%i" $path`;
hash=`cat $path | md5sum | cut -d" " -f1`;
printf "Name: %s - InodeContext<0x%X> - MD5: %s\n" $path $inode $hash;'
答案 0 :(得分:3)
直接的错误是传递给bash -c "...commands..."
的第一个参数以$0
结尾,而不是以$1
结尾。另外,由于您在"...commands..."
周围使用了双引号,因此 calling shell将在脚本传递到子shell时对所有变量进行插值。
但是,这似乎确实令人费解。在不知道您确切希望完成什么的情况下,这是一种推测,但是我会采用类似的方式
time find BASE_DIR -maxdepth 1 -mindepth 1 -type d \
-execdir find . -type f -exec bash -c '
for f; do
inode=$(stat -c "%i" "$f")
md5=$(md5 <"$f" | cut -d " " -f1)
printf "Name: %s - Inode: 0x%X - MD5: %s\n" "$f" "$inode" "$md5"
done' _ {} \\+ \;
如果您可以解释如何对输出进行排序,则可以将排序键放在printf
中,并在最后进行排序。
答案 1 :(得分:0)
一次做一件事情并做好一件事情,我发现它更容易。
-I{}
选项表示-n1
。我仍然习惯使用与-i
相同的-I{}
选项。
find BASE_DIR -maxdepth 1 -mindepth 1 -type d |
# what's the point in sorting before -P100?
xargs -P100 -i find {} -type f |
sort |
# run stat and md5sum for the same file
# output: <filename> <stat output> <md5sum>
xargs -n1 bash -ce '
printf "%s\n" "$1";
stat -c "%i" "$1";
md5sum "$1" | cut -d" " -f1;
' -- |
# for every three (filename, stat, md5sum) arguments run printf
xargs -n3 printf 'Name: %s - Inode: 0x%X - MD5: %s\n'