передача аргументов скрипту bash с использованием xargs - PullRequest
0 голосов
/ 04 марта 2019

Я запускаю следующую команду bash для форматирования журнала с файловым индексом и хэшем:

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

Один и тот же файл каждый раз.Как правильно передать аргументы в 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;'

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Мне проще, если делать что-то по одному и делать хорошо.

Опция -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'
0 голосов
/ 04 марта 2019

Непосредственной ошибкой является то, что первый аргумент, переданный bash -c "...commands...", заканчивается $0, а не $1.Кроме того, поскольку вы использовали двойные кавычки вокруг "...commands...", оболочка , вызывающая , будет интерполировать все переменные в момент передачи скрипта в подоболочку.

Хотя это кажется действительно запутанным.Без знания того, что именно вы надеетесь достичь, это довольно умозрительно, но я бы подошел к этому примерно так:

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 и отсортировать по нему в конце.

Обратите также внимание на то, как мы избегаем прописных букв в частных переменных.

...