使用xargs将参数传递给bash脚本

问题描述 投票:0回答:2

我运行以下bash命令来格式化带有文件inode和hash的日志:

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;'
bash xargs
2个回答
3
投票

直接错误是传递给bash -c "...commands..."的第一个参数最终在$0中,而不是在$1中。另外,因为你在"...commands..."周围使用了双引号,所以调用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中并在结尾处按排序键排序。

另请注意我们如何avoid uppercase in private variables.


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'
© www.soinside.com 2019 - 2024. All rights reserved.