Подтвердить что ты не робот

Bash: создайте файл, если он не существует, в противном случае проверьте, можно ли его записать

У меня есть программа bash, которая будет записывать в выходной файл. Этот файл может существовать или не существовать, но script должен проверять разрешения и отказываться раньше. Я не могу найти элегантный способ сделать это. Вот что я пробовал.

set +e
touch $file
set -e

if [ $? -ne 0 ]; then exit;fi

Я поддерживаю set -e для этого script, поэтому он терпит неудачу, если в любой строке есть ошибка. Есть ли более простой способ сделать выше script?

4b9b3361

Ответ 1

Вместо проверки $? в другой строке немедленно проверьте возвращаемое значение следующим образом:

touch file || exit

Пока ваш umask не ограничивает установку бита записи, вы можете просто положиться на возвращаемое значение touch

Ответ 2

Зачем усложнять?

file=exists_and_writeable

if [ ! -e "$file" ] ; then
    touch "$file"
fi

if [ ! -w "$file" ] ; then
    echo cannot write to $file
    exit 1
fi

Или, более кратко,

( [ -e "$file" ] || touch "$file" ) && [ ! -w "$file" ] && echo cannot write to $file && exit 1

Ответ 3

Почему сервер script не работает раньше? Разделив записываемый тест и файл open(), вы вводите условие гонки. Вместо этого, почему бы не попытаться открыть (усекать/добавить) файл для записи и справиться с ошибкой, если это произойдет? Что-то вроде:

$ echo foo > output.txt
$ if [ $? -ne 0 ]; then die("Couldn't echo foo")

Как упоминают другие, опция "noclobber" может быть полезна, если вы хотите избежать перезаписи существующих файлов.

Ответ 4

Вы можете использовать -w, чтобы проверить, доступен ли файл для записи (найдите его на странице bash).

if [[ ! -w $file ]]; then exit; fi

Ответ 5

Откройте файл для записи. В оболочке это делается с перенаправлением вывода. Вы можете перенаправить стандартный вывод оболочки, поместив перенаправление на встроенный exec без аргументов.

set -e
exec >shell.out  # exit if shell.out can't be opened
echo "This will appear in shell.out"

Убедитесь, что вы не установили параметр noclobber (который полезен в интерактивном режиме, но часто неприменим в сценариях). Используйте >, если вы хотите обрезать файл, если он существует, и >>, если вы хотите добавить его.

Если вы хотите протестировать разрешения, вы можете запустить : >foo.out, чтобы создать файл (или усечь его, если он существует).

Если вам нужны только некоторые команды для записи в файл, откройте его на каком-то другом дескрипторе, а затем перенаправьте по мере необходимости.

set -e
exec 3>foo.out
echo "This will appear on the standard output"
echo >&3 "This will appear in foo.out"
echo "This will appear both on standard output and in foo.out" | tee /dev/fd/3

(/dev/fd не поддерживается везде, он доступен, по крайней мере, в Linux, * BSD, Solaris и Cygwin.)