备份bash脚本的第一个参数

时间:2018-03-21 06:30:51

标签: linux bash

我编写了一个脚本来备份用户使用脚本输入的第一个参数:

# Sample data
df <- read.table(text =
    "Plant Branch Pod_B Flow_Miss Pod_A Flow_T Trt     Dmg
1     1   1.00     0        16    20  36.0  Early     1
2     1   2.00     0         1    17  18.0  Early     1
3     1   3.00     0         0    17  17.0  Early     1
4     1   4.00     0         3    14  17.0  Early     1
5     1   5.00     5         2     4  11.0  Early     1
6     1   6.00     0         3     7  10.0  Early     1
7     1   7.00     0         4     6  10.0  Early     1
8     1   8.00     0        13     6  19.0  Early     1
9     1   9.00     0         2     7   9.00 Early     1
10     1  10.0      0         2     3   5.00 Early     1
11     1  10.0      0         2     3   20.00 Late     1", header = T)

我想从脚本中得到的结果是

  1. 备份文件夹用户输入的第一个参数
  2. 将备份文件保存到用户输入日期时间格式的文件夹中。
  3. 但是当我尝试输入参数时脚本没有运行。脚本出了什么问题?

2 个答案:

答案 0 :(得分:2)

您的脚本的备份部分似乎运行良好,但不是您检查$1不为空的部分。

首先,您需要$1周围的引号,以防止它消耗任何东西。如果没有引号,shell会将其视为

if [ -eq 0 ]

并抛出错误。

其次,最好使用-z运算符来测试变量是否存在:

if [ -z "$1" ]

现在你的脚本应该按预期工作了

答案 1 :(得分:1)

我看到了几个问题:

  • 正如H.Gourlé指出的那样,对是否通过论证的考验是错误的。使用if [ -z "$1" ]检查缺失/空白参数。
  • 此外,在双引号中包装变量引用几乎总是一个好主意,如上面的"$1"所示。您在测试中是否存在$file,而不是tar命令。有些地方可以放弃双引号,但规则很复杂; 总是双引号更容易。
  • 除了检查是否已通过$1之外,我还建议检查它是否与实际存在的目录(或可能是文件)相对应。使用类似的东西:

    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,请注意错误消息如何以$0(脚本运行的名称)开头,并指向错误输出(>&2部分)?这些都是错误消息的标准约定。

  • 这不严重,但它确实让我感到困惑:你计算$1/$(date +"_%Y-%m-%d").tar.gz,将其存储在file变量中,测试是否存在该名称的某些内容,然后计算创建备份文件时再次。没有理由这样做;只需再次使用file变量。它让我烦恼的部分原因在于它违反了DRY(“不要重复自己”)的原则,部分原因是如果你改变了命名约定,你必须在两个地方一致地改变它,否则脚本将无法工作,部分原因是因为原则上脚本可能会在午夜运行,第一次计算会得到一天而第二次会得到不同的一天。
  • 说到命名约定,存储备份文件的方式存在问题。如果您将其放在正在备份的目录中,那么第一天您将获得包含该目录的先前内容的.tar.gz文件。第二天,您将获得包含常规内容和第一个备份文件的文件。因此,第二天的备份将大约两倍。第三天的备份将包含常规内容,以及前两个备份文件,因此它将是原来的四倍。第四天将是8倍,然后是16倍,然后是32倍等等。

    您需要将备份文件存储在外部正在备份的目录中,或者将--exclude="*.tar.gz"之类的内容添加到tar的参数中。 --exclude选项的缺点是它可能会从备份中排除其他.tar.gz文件,所以我真的推荐第一个选项。如果您遵循我的建议,在任何地方使用"$file"而不是重新计算名称,您只需在一个地方进行更改即可更改备份的位置。

最后一点:通过shellcheck.net运行您的脚本。在你发现困难之前,它会指出很多常见错误和不良做法。

这是脚本的更正版本(将备份存储在目录中,不包括.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