创建文件的Shell脚本(如果不存在)?


19

我需要创建一个Shell脚本来检查文件是否存在,如果不存在,请创建该文件并继续执行下一个命令,或者仅继续进行下一个命令。我所没有做的。

#!/bin/bash

# Check for the file that gets created when the script successfully finishes.
if [! -f /Scripts/file.txt]
then
: # Do nothing. Go to the next step?
else
mkdir /Scripts # file.txt will come at the end of the script
fi

# Next command (macOS preference setting)
defaults write ...

回报是

line 5: [!: command not found
mkdir: /Scripts: File exists

不知道该怎么办。Google搜索带给我的每个地方都代表不同的地方。


6
将您的代码放入shellcheck.net并查看其提出的建议
roaima

12
有什么原因不能只touch删除文件并跳过条件文件?
kirkpatt

下面的其他答案解决了语法错误([和之间缺少空格!),但是在这里指出这[是Unix上的实际命令可能会有所帮助。Unix命令在命令名称及其参数之间需要一些空格。是的,它也是Bash 内置的,但/usr/bin/[在大多数系统上也有二进制文件。
TheDudeAbides

Answers:


43

可能更简单的解决方案,无需进行显式测试,只需使用:

mkdir -p /Scripts
touch /Scripts/file.txt

如果您不希望file.txt通过更改现有项的“修改”时间touch,则可以使用touch -a /Scripts/file.txttouch仅更改“访问”和“更改”时间。


1
如果您不关心mtime,可以使用>>/Scripts/file.txt。这将打开文件进行追加,如果不存在则创建它。
kojiro

29

之所以会收到错误,是因为它们之间没有空格[!但是代码中也存在一些缺陷。首先,您要检查文件是否不存在,如果不存在,则什么也不做。如果文件确实存在,则您正在建立目录(但是不做任何操作来创建文件)。

您也不需要null操作,只需执行以下操作即可:

#! /bin/bash -
if [[ ! -e /Scripts/file.txt ]]; then
    mkdir -p /Scripts
    touch /Scripts/file.txt
fi

[command2]

这正在检查是否/Scripts/file.txt不存在,它将创建/Scripts目录,然后创建file.txt文件。如果需要,您也可以单独检查目录是否存在。另外请注意,我使用的-e不是-f您所要求的,而是简单地检查文件的存在,该操作-e将在-f检查文件是否为“常规文件”的情况下进行:http://tldp.org/LDP/abs/html/fto。 html


感谢@roaima,我已经用您的建议更新了我的答案。
Jesse_b

什么是文件不存在,但目录呢?
蚂蚁

3
@Ant:mkdir -p:创建所有必要的目录,而不用抱怨是否已经存在。例如:mkdir / home / user1 / tmp:将创建此层次结构,而与/ home或/ home / user1目录事先存在的事实无关。touch也将仅更新现有文件的时间,或者如果不存在文件,则创建一个新文件。甚至可以摆脱if ... then部分,因为如果要确保这些目录存在并且其中存在该文件,只需启动这两个命令就可以了。
Olivier Dulac

我知道了!感谢您的澄清:)
蚂蚁

11

首先,shell脚本不是bash脚本,因此让您的代码更通用:

#!/bin/sh

每个Posix系统都必须具有该文件。bash严格是可选的。

无需测试目录是否存在,只需

dir=/Scripts
mkdir -p $dir

要创建不存在的文件,

filename=$dir/file.txt
test -f $filename || touch $filename

或者,如果您愿意,

filename=$dir/file.txt
if [ ! -f $filename ]
then
    touch $filename
fi


3
#!/bin/bash

# Check for the file that gets created when the script successfully finishes.
CHECKFILE="/Scripts/file.txt"

CHECKDIR=$( dirname "$CHECKFILE" )

# The directory with the file must exist
mkdir -p "$CHECKDIR"
if [ ! -f "$CHECKFILE" ]; then
    # What to do if the file is not there
fi
touch "$CHECKFILE"

上述假设不存在“招数”,如创建一个目录名为/Scripts/file.txt(这可能是迫使脚本总是进入,如果分支的一种方式)。如果“文件”是目录,则-f测试将失败,并且touch命令将保持不变。


0

我的方法

#!/bin/sh

# input might contains spaces and other characters
FILEPATH="/tmp/some where/the file.blah"

# extract the file + dir names
FILE="`basename "${FILEPATH}"`"
DIR="`dirname "${FILEPATH}"`"

# create the dir, then the file
mkdir -p "${DIR}" && touch "${DIR}/${FILE}"

# show result
ls -l "$FILEPATH"

输出

  ./dofile.sh
  -rw-r--r-- 1 jmullee jmullee 0 Nov 15 21:23 /tmp/some where/the file.blah


1
您不检查文件是否存在
PiedPiper

@piepdpiper他做什么,这是impliciit中touchmkdir -p
xenoid

具有更多检查的相同想法看起来像:D = / boot / bork;F =正 mkdir -p“ $ D” && {触摸“ $ D / $ F” && echo“创建$ D / $ F OK”; } || {echo“无法创建目录'$ D'”; }
jmullee
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.