Моя проблема (у сценарії з #!/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' {} +