[英]Backup the first argument on bash script
I wrote a script to backup the first argument that the user input with the script: 我编写了一个脚本来备份用户使用脚本输入的第一个参数:
#!/bin/bash
file=$1/$(date +"_%Y-%m-%d").tar.gz
if [ $1 -eq 0 ]
then
echo "We need first argument to backup"
else
if [ ! -e "$file" ]; then
tar -zcvf $1/$(date +"_%Y-%m-%d").tar.gz $1
else
exit
fi
fi
The result that i want from the script is 我想要的脚本结果是
but the script is not running when I try to input the argument. 但是当我尝试输入参数时脚本未运行。 What's wrong with the script?
脚本出了什么问题?
The backup part of your script seem to be working well, but not the part where you check that $1
is not empty. 脚本的备份部分似乎运行良好,但不能检查
$1
是否为空。
Firstly you would need quotes around $1
, to prevent that it expends to nothing. 首先,您需要在
$1
左右$1
引号,以防止其花费为零。 Without the quotes the shell sees it as 没有引号,shell会将其视为
if [ -eq 0 ]
and throws an error. 并引发错误。
Secondly it would be better to use the -z
operator to test if the variable exists: 其次,最好使用
-z
运算符来测试变量是否存在:
if [ -z "$1" ]
Now you script should work as expected 现在您的脚本应该可以按预期工作
I see several problems: 我看到几个问题:
if [ -z "$1" ]
to check for a missing/blank argument. if [ -z "$1" ]
用于检查参数是否缺失。 "$1"
above. "$1"
。 You do this in the test for whether $file
exists, but not in the tar
command. $file
是否存在,但在tar
命令中不这样做。 There are places where it's safe to leave the double-quotes off, but the rules are complicated; In addition to checking whether $1
was passed, I'd recommend checking whether it corresponds to a directory (or possibly file) that actually exists. 除了检查是否传递了
$1
,我还建议检查它是否对应于实际存在的目录(或可能是文件)。 Use something like: 使用类似:
if [ -z "$1" ]; then echo "$0: We need first argument to backup" >&2 elif [ ! -d "$1" ]; then echo "$0: backup source $1 not found or is not a directory" >&2
BTW, note how the error messages start with $0
(the name the script was run as) and are directed to error output (the >&2
part)? 顺便说一句,请注意错误消息如何以
$0
开头(运行脚本的名称)并定向到错误输出( >&2
部分)? These are both standard conventions for error messages. 这些都是错误消息的标准约定。
$1/$(date +"_%Y-%m-%d").tar.gz
, store it in the file
variable, test to see whether something by that name exists, and then calculate it again when creating the backup file. $1/$(date +"_%Y-%m-%d").tar.gz
,将其存储在file
变量中,测试是否通过该名称存在,然后在创建备份文件时再次计算 。 There's no reason to do that; file
variable again. file
变量。 The reason it bugs me is partly that it violates the DRY ("Don't Repeat Yourself") principle, partly that if you ever change the naming convention you have to change it consistently in two places or the script will not work, and partly because in principle it's possible that the script will run just at midnight, and the first calculation will get one day and the second will get a different day. Speaking of naming conventions, there's a problem with how you store the backup file. 说到命名约定,存储备份文件的方式存在问题。 If you put it in the directory that's being backed up, then the first day you'll get a .tar.gz file containing the previous contents of the directory.
如果将其放在要备份的目录中,则第一天您将获得一个.tar.gz文件,其中包含该目录的先前内容。 The second day you'll get a file containing the regular contents plus the first backup file .
第二天,您将获得一个包含常规内容的文件以及第一个备份文件 。 Thus, the second day's backup will be about twice as big.
因此,第二天的备份大约是原来的两倍。 The third day's backup will contain the regular contents, plus the first two backup files, so it'll be four times as big.
第三天的备份将包含常规内容以及前两个备份文件,因此它将是原来的四倍。 And the fourth day's will be eight times as big, then 16 times, then 32 times, etc.
第四天将是原来的八倍,然后是16倍,然后是32倍,依此类推。
You need to either store the backup file somewhere outside the directory being backed up, or add something like --exclude="*.tar.gz"
to the arguments to tar
. 您需要将备份文件存储在要备份的目录之外的某个地方,或者在
tar
的参数中添加--exclude="*.tar.gz"
之类的内容。 The disadvantage of the --exclude
option is that it may exclude other .tar.gz files from the backup, so I'd really recommend the first option. --exclude
选项的缺点是它可能会从备份中排除其他.tar.gz文件,因此,我真的建议您使用第一个选项。 And if you followed my advice about using "$file"
everywhere instead of recalculating the name, you only need to make a change in one place to change where the backup goes. 而且,如果您遵循我的建议在各处使用
"$file"
而不是重新计算名称,则只需在一个位置进行更改即可更改备份的位置。
One final note: run your scripts through shellcheck.net . 最后一点:通过shellcheck.net运行脚本。 It'll point out a lot of common errors and bad practices before you discover them the hard way.
在用困难的方式发现它们之前,它将指出许多常见的错误和不良做法。
Here's a corrected version of the script (storing the backup in the directory, and excluding .tar.gz files; again, I recommend the other option): 这是脚本的更正版本(将备份存储在目录中,并且排除.tar.gz文件;再次,我建议另一个选择):
#!/bin/bash
file="$1/$(date +"_%Y-%m-%d").tar.gz"
if [ -z "$1" ]; then
echo "$0: We need first argument to backup" >&2
elif [ ! -d "$1" ]; then
echo "$0: backup source $1 not found or is not a directory" >&2
elif [ -e "$file" ]; then
echo "$0: A backup already exists for today" >&2
else
tar --exclude="*.tar.gz" -zcvf "$file" "$1"
fi
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.