shell脚本变量被截断-为什么

shell脚本变量被截断-为什么,shell,Shell,我一直在尝试定制这个非常有用(原则上)的s3脚本备份。 我真的不是一个真正意义上的shell脚本编写者,我不明白为什么要写这行 正在截断变量 例如 DB=abcdefg abcdefg_USER=testuser USER=$(eval echo \$${DB}_USER) eval语句返回bcdefg_USER,因此截断变量并回显bcdefg_USER而不是abcdefg_USER,因此不计算变量abcdefg_USER 在AmazonLinuxEC2实例上运行 任何人都可以向我解释我遗漏

我一直在尝试定制这个非常有用(原则上)的s3脚本备份。 我真的不是一个真正意义上的shell脚本编写者,我不明白为什么要写这行 正在截断变量

例如

DB=abcdefg
abcdefg_USER=testuser

USER=$(eval echo \$${DB}_USER)
eval语句返回bcdefg_USER,因此截断变量并回显bcdefg_USER而不是abcdefg_USER,因此不计算变量abcdefg_USER

在AmazonLinuxEC2实例上运行

任何人都可以向我解释我遗漏了什么,我试着玩过逃跑和背带等游戏,并重复了过程中的每一个阶段,但无法掌握到底发生了什么

谢谢

全文如下:

    ## Specify data base schemas to backup and credentials
DATABASES="wp myotherdb"

## Syntax databasename as per above _USER and _PW
wp_USER=username
wp_PW=password
myotherdb_USER=username
myotherdb_PW=password

## Specify directories to backup (it's clever to use relaive paths)
DIRECTORIES="/var/www root etc/cron.daily etc/cron.monthly etc/apache2 etc/mysql etc/php5" 

## Initialize some variables
DATE=$(date +%d)
BACKUP_DIRECTORY=/tmp/backups
S3_CMD="s3cmd"

## Specify where the backups should be placed
S3_BUCKET_URL=s3://mybackupbucket/$DATE/

## The script
cd /
mkdir -p $BACKUP_DIRECTORY
rm -rf $BACKUP_DIRECTORY/*

## Backup MySQL:s
for DB in $DATABASES
do
BACKUP_FILE=$BACKUP_DIRECTORY/${DB}.sql
USER=$(eval echo \$${DB}_USER)
PASSWORD=$(eval echo \$${DB}_PW)
/usr/bin/mysqldump -v -u $USER --password=$PASSWORD -h localhost -r $BACKUP_FILE $DB 2>&1
gzip $BACKUP_FILE 2>&1
$S3_CMD put ${BACKUP_FILE}.gz $S3_BUCKET_URL 2>&1
done

## Backup of config directories
for DIR in $DIRECTORIES
do
BACKUP_FILE=$BACKUP_DIRECTORY/$(echo $DIR | sed 's/\//-/g').tgz
tar zcvf ${BACKUP_FILE} $DIR 2>&1
$S3_CMD put ${BACKUP_FILE} $S3_BUCKET_URL 2>&1
done

假设您使用的是bash,这就是如何避免
eval

$ DB=abcdefg
$ abcdefg_USER=testuser
$ tmpvar=${DB}_USER
$ USER=${!tmpvar}
$ echo $USER
testuser

如果您有BASH版本4,请考虑使用关联数组:

$ declare -A users
$ users[abcdefg]=testuser
$ echo "${users[$DB]}"
testuser

假设您使用的是bash,这就是如何避免
eval

$ DB=abcdefg
$ abcdefg_USER=testuser
$ tmpvar=${DB}_USER
$ USER=${!tmpvar}
$ echo $USER
testuser

如果您有BASH版本4,请考虑使用关联数组:

$ declare -A users
$ users[abcdefg]=testuser
$ echo "${users[$DB]}"
testuser

假设您使用的是bash,这就是如何避免
eval

$ DB=abcdefg
$ abcdefg_USER=testuser
$ tmpvar=${DB}_USER
$ USER=${!tmpvar}
$ echo $USER
testuser

如果您有BASH版本4,请考虑使用关联数组:

$ declare -A users
$ users[abcdefg]=testuser
$ echo "${users[$DB]}"
testuser

假设您使用的是bash,这就是如何避免
eval

$ DB=abcdefg
$ abcdefg_USER=testuser
$ tmpvar=${DB}_USER
$ USER=${!tmpvar}
$ echo $USER
testuser

如果您有BASH版本4,请考虑使用关联数组:

$ declare -A users
$ users[abcdefg]=testuser
$ echo "${users[$DB]}"
testuser

您遇到了一些奇怪的错误,包括命令替换和
echo

当使用
eval
访问计算变量名时,没有必要通过将
echo
封装在进程替换中而使事情复杂化。尝试这种模式,它应该在任何类似POSIX的shell中都能正常工作

eval FINAL_VALUE=\$${COMPUTED_VAR_PREFIX}_FIXED_SUFFIX

也就是说,只需生成所需变量赋值的源代码,然后
eval
该代码。

您遇到了一些奇怪的错误,包括命令替换和
echo

当使用
eval
访问计算变量名时,没有必要通过将
echo
封装在进程替换中而使事情复杂化。尝试这种模式,它应该在任何类似POSIX的shell中都能正常工作

eval FINAL_VALUE=\$${COMPUTED_VAR_PREFIX}_FIXED_SUFFIX

也就是说,只需生成所需变量赋值的源代码,然后
eval
该代码。

您遇到了一些奇怪的错误,包括命令替换和
echo

当使用
eval
访问计算变量名时,没有必要通过将
echo
封装在进程替换中而使事情复杂化。尝试这种模式,它应该在任何类似POSIX的shell中都能正常工作

eval FINAL_VALUE=\$${COMPUTED_VAR_PREFIX}_FIXED_SUFFIX

也就是说,只需生成所需变量赋值的源代码,然后
eval
该代码。

您遇到了一些奇怪的错误,包括命令替换和
echo

当使用
eval
访问计算变量名时,没有必要通过将
echo
封装在进程替换中而使事情复杂化。尝试这种模式,它应该在任何类似POSIX的shell中都能正常工作

eval FINAL_VALUE=\$${COMPUTED_VAR_PREFIX}_FIXED_SUFFIX

也就是说,只需生成所需变量赋值的源代码,然后
eval
该代码。

当我运行您的示例时,
USER
按预期设置为
testuser
。这不是发生在你身上吗?您能否制作一个测试用例,一个显示问题的脚本的较短版本?(有关可以省略的内容的提示,请参见)请注意,
eval
命令不会回显任何内容;
echo
命令不起作用。将
${DB}
\u testuser
粘合在一起是在评估
回波
之前进行扩展的一部分。如果一个角色在这一点上被砍掉,那就相当神秘了;它生成了错误的变量名,因此
echo
不会回显任何内容(如果我们使用
set-u
捕获未定义变量的使用,甚至会引发错误)。“amazon linux ec2”不是很有用:事实证明,很难获得有关linux的amazon发行版的任何详细规范。您正在使用
#/bin/sh
#/脚本中的bin/bash
?它使用的是什么shell,什么版本。感谢您的评论和指点,非常感谢。下次我将通过详细说明哪个shell等来更好地指定问题。当我运行您的示例时,
USER
按预期设置为
testuser
。这不是发生在你身上吗?您能否制作一个测试用例,一个显示问题的脚本的较短版本?(有关可以省略的内容的提示,请参见)请注意,
eval
命令不会回显任何内容;
echo
命令不起作用。将
${DB}
\u testuser
粘合在一起是在评估
回波
之前进行扩展的一部分。如果一个角色在这一点上被砍掉,那就相当神秘了;它生成了错误的变量名,因此
echo
不会回显任何内容(如果我们使用
set-u
捕获未定义变量的使用,甚至会引发错误)。“amazon linux ec2”不是很有用:事实证明,很难获得有关linux的amazon发行版的任何详细规范。您正在使用
#/bin/sh
#/脚本中的bin/bash
?它使用的是什么shell,什么版本。感谢您的评论和指点,非常感谢。下次我将通过详细说明哪个shell等来更好地指定问题。当我运行您的示例时,
USER
按预期设置为
testuser
。这不是发生在你身上吗?您能否制作一个测试用例,一个显示问题的脚本的较短版本?(有关可以省略的内容的提示,请参见)请注意,
eval
命令不会回显任何内容;
echo
命令不起作用。将
${DB}
\u testuser
粘合在一起是在