Моя проблема (у сценарії з #!/bin/sh
) полягає в наступному: я намагаюся перевірити всі файли в каталозі для архівних цілей. Файл контрольної суми (в моєму випадку sha1) з усіма іменами файлів повинен міститися в одному каталозі. Скажімо, у нас є каталог ~/test
з файлами f1
та f2
:.
mkdir ~/test
cd ~/test
echo "hello" > f1
echo "world" > f2
Тепер обчислюємо контрольні суми за допомогою
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum
робить саме те, що я хочу, він перераховує всі файли поточного каталогу і обчислює ша1 суми (maxdepth може бути змінено пізніше). Вихід на STDOUT:
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
На жаль, при спробі зберегти це у файл із
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum > sums.sha1
отриманий файл відображає контрольну суму для себе:
da39a3ee5e6b4b0d3255bfef95601890afd80709 sums.sha1
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
і тому не вдається пізніше shasum --check
через очевидну проблему додаткової модифікації файлу при збереженні останньої суми.
Я озирнувся і, використовуючи -p
прапор для xargs
, я виявив, що він якимось чином створює вихідний файл перед тим, як навіть виконати команду find, тому додатковий файл знайдеться і буде перевірено ...
Я знаю, що як вирішення проблеми я міг би зберегти контрольну суму в інше місце (тимчасовий каталог через mktemp
) або виключити її в пошуку спеціально, але я хотів би зрозуміти, чому вона поводиться так, як це відбувається - що, на мої очі, не так корисно, наприклад, якщо перша команда перевірить, чи файл виводу вже на диску, він ніколи не отримає правильну відповідь ...
sh
викликів. Зауважте, що вам потрібен аргумент для $0
цього {}
.
tee
, зникла? Я спробував це, і він працює добре, я також придушив STDOUT з додаванням 1>/dev/null
. Чи щось не було у відповіді або це помилка?
xargs
, що саме оболонка створює цей файл, тому що перед виконанням будь-якої команди спочатку оболонка перенаправляє всі вхідні, вихідні та трубові, так що приfind
запуску вихідний файл вже існує. Використовуйте-exec
замість цього:find -maxdepth 1 -type f -exec sh -c 'shasum "$@" > sums.sha1' {} +