Linux Bash:如果文件不存在则创建一个文件,否则检查它是否可写

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4511403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:02:01  来源:igfitidea点击:

Bash: Create a file if it does not exist, otherwise check to see if it is writeable

linuxbash

提问by User1

I have a bash program that will write to an output file. This file may or may not exist, but the script must check permissions and fail early. I can't find an elegant way to make this happen. Here's what I have tried.

我有一个将写入输出文件的 bash 程序。该文件可能存在也可能不存在,但脚本必须检查权限并尽早失败。我找不到一种优雅的方式来实现这一点。这是我尝试过的。

set +e
touch $file
set -e

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

I keep set -eon for this script so it fails if there is ever an error on any line. Is there an easier way to do the above script?

我继续set -e使用这个脚本,所以如果任何一行出现错误,它就会失败。有没有更简单的方法来执行上述脚本?

采纳答案by SiegeX

Rather than check $?on a different line, check the return value immediately like this:

与其检查$?不同的行,不如像这样立即检查返回值:

touch file || exit

As long as your umaskdoesn't restrict the write bit from being set, you can just rely on the return value of touch

只要你umask不限制写入位被设置,你就可以依赖于的返回值touch

回答by a'r

You can use -wto check if a file is writable (search for it in the bash man page).

您可以-w用来检查文件是否可写(在 bash 手册页中搜索它)。

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

回答by Gilles 'SO- stop being evil'

Open the file for writing. In the shell, this is done with an output redirection. You can redirect the shell's standard output by putting the redirection on the execbuilt-in with no argument.

打开文件进行写入。在 shell 中,这是通过输出重定向完成的。您可以通过将重定向放在exec不带参数的内置程序上来重定向 shell 的标准输出。

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

Make sure you haven't set the noclobberoption (which is useful interactively but often unusable in scripts). Use >if you want to truncate the file if it exists, and >>if you want to append instead.

确保您没有设置该noclobber选项(这在交互中很有用,但在脚本中通常无法使用)。使用>,如果你想截断该文件是否存在,>>如果你想,而不是追加。

If you only want to test permissions, you can run : >foo.outto create the file (or truncate it if it exists).

如果您只想测试权限,您可以运行: >foo.out以创建文件(如果存在则将其截断)。

If you only want some commands to write to the file, open it on some other descriptor, then redirect as needed.

如果您只想将某些命令写入文件,请在其他描述符上打开它,然后根据需要重定向。

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/fdis not supported everywhere; it's available at least on Linux, *BSD, Solaris and Cygwin.)

/dev/fd并非所有地方都支持;它至少在 Linux、*BSD、Solaris 和 Cygwin 上可用。)

回答by sorpigal

Why complicate things?

为什么要把事情复杂化?

file=exists_and_writeable

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

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

Or, more concisely,

或者,更简洁地说,

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

回答by Phil

Why must the script fail early? By separating the writable test and the file open() you introduce a race condition. Instead, why not try to open (truncate/append) the file for writing, and deal with the error if it occurs? Something like:

为什么脚本必须提前失败?通过将可写测试和文件 open() 分开,您引入了竞争条件。相反,为什么不尝试打开(截断/追加)文件进行写入,并在发生错误时进行处理?就像是:

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

As others mention, the "noclobber" option might be useful if you want to avoid overwriting existing files.

正如其他人提到的,如果您想避免覆盖现有文件,“noclobber”选项可能很有用。