我正在编写第一个 bash 脚本来自动执行备份。我几乎陷入了第一个障碍。
我想使用变量为 tar 存档创建文件名。我想要一个看起来像hostname date time.tar.bz2
.我可以使用它自己获得它$(hostname)_$(date +"%FT%T")
,但我似乎无法将其放入变量中。
我的“测试脚本”如下所示:
#! /bin/bash
NAME=$($(hostname)_$(date +"%FT%T"))
tar -cjvf "$(NAME).tar.bz2" testing testing2
(其中testing
和testing2
是用于测试的虚拟目录。)
不幸的是,它这样做:
$ scripts/trial.sh
scripts/trial.sh: line 6: NAME: command not found
Thu Jun 10 23:11:06 AEST 2021
我试图将声明分解NAME
为解决方法
#! /bin/bash
## test of bits and pieces
NAME=$(hostname)_$(date +"%FT%T")
NAME_VAR=$(NAME)
Test=$(date)
echo $NAME_VAR
echo $Test
tar -cjvf "$(NAME_VAR).tar.bz2" testing testing2
在终端中得到以下内容:
$ scripts/trial.sh
scripts/trial.sh: line 6: NAME: command not found
Thu Jun 10 23:34:37 AEST 2021
scripts/trial.sh: line 13: NAME_VAR: command not found
testing/
testing2/
我只是不明白为什么会发生这种情况。我缺少什么?
答案1
如果这是您第一次尝试 shell 脚本编写,我建议使用外壳检查“校对”shell 脚本;它也可以作为许多 Linux 发行版上的独立程序使用。
对于您面临的问题:您似乎混淆了 shell 和 Makefile 语法来取消引用变量。在 shell 中,$NAME
是 变量 的值NAME
,而$(NAME)
会尝试执行命令NAME
并返回该命令的输出 - 所谓的“命令替换”(您在填写NAME
“点滴测试”解决方法时正确使用了它)。
所以,更正后的脚本看起来像
NAME="$(hostname)_$(date +"%FT%T")"
tar -cjvf "$NAME.tar.bz2" testing testing2
作为旁注
- 不应使用全大写的变量名,除非将它们作为环境变量导出到 shell,否则它们可能会发生冲突并覆盖重要的环境变量,例如
$PATH
. - 一定要正确引用你的变量引用,特别是当变量包含文件名时。否则,您的 shell 脚本可能会偶然发现带有特殊字符的文件名,例如空格、、、
*
换行符?
(是的,即使这些字符也可以出现在文件名中!)等。
我建议你看一下
供进一步阅读。
答案2
第一行应该是:
NAME=$(hostname)_$(date +"%FT%T")
按照您的方式,它将使用命令替换并将输出视为命令,因为它不存在,您将收到错误。
最后一行可能是这样的:
tar -cjvf "$NAME.tar.bz2" testing testing2
为了将来参考,您可以使用 shellcheck.net 来验证您的脚本。