Причиной ошибки является наличие пробелов или других специальных символов в именах файлов под ./img
.
Вместо опции -print
для find
используйте -print0
и соответствующую опцию -0
для `xargs':
find ./img ! -path ./img -mtime -7 -print0 | xargs -0 tar uvf `date --rfc-3339=date`-package.tar
Да, вы можете улучшить код.
Оператор select
в bash
обеспечивает способ отображения меню, а также обеспечивает базовый цикл ввода.
#!/bin/bash
menu=(
Work
School
Shopping
)
PS3='What is this note for? '
while true; do
unset outfile
select word in Exit "${menu[@]}"; do
case $REPLY in
1)
echo 'Bye!'
exit ;;
[2-4])
outfile="$HOME/${word,,}-notes.txt" ;;
*)
echo 'Invalid choice, try again' >&2
esac
if [ -n "$outfile" ]; then
break
fi
done
IFS= read -r -p 'Enter note: '
printf '%s:\t%s\n' "$(date +%d-%B-%Y)" "$REPLY" >>"$outfile"
printf 'Note added to "%s"\n' "$outfile"
done
Еще одно изменение здесь заключается в том, что я прошу настоящую заметку только в одном месте. Это облегчает чтение кода и упрощает его обслуживание.
Очевидно, что case... esac
можно заменить серией утверждений if... then... elif... fi
, если так удобнее. Внутренний оператор break
прерывает цикл select
, если был сделан правильный выбор. Это приводит нас к внешнему циклу, который затем запрашивает у пользователя текст и сохраняет его в файл, прежде чем вернуться к отображению меню. Выбор Exit
в меню позволяет выйти из скрипта.
Небольшое замечание состоит в том, что
while [ true ]
в вашем коде имеет тот же эффект, что и
while [ false ]
или, как и
while [ bumblebee ]
Это связано с тем, что когда [... ]
содержит одно слово, это слово интерпретируется как строка. Если строка не -пуста, проверка верна .
В моем коде я использую
while true
, которая на самом деле выполняет утилиту true
, которая всегда возвращает значение true .