我对bash脚本感到困惑。
我有以下代码:
function grep_search() {
magic_way_to_define_magic_variable_$1=`ls | tail -1`
echo $magic_variable_$1
}
我希望能够创建一个变量名,其中包含命令的第一个参数,并承载例如ls的最后一行的值。
为了说明我想要的:
$ ls | tail -1
stack-overflow.txt
$ grep_search() open_box
stack-overflow.txt
那么,我应该如何定义/声明$magic_way_to_define_magic_variable_$1,我应该如何在脚本中调用它?
我已经试过eval, ${…}, \$${...},但我还是很困惑。
将两个评分较高的答案结合成一个完整的例子,希望有用且不言自明:
#!/bin/bash
intro="You know what,"
pet1="cat"
pet2="chicken"
pet3="cow"
pet4="dog"
pet5="pig"
# Setting and reading dynamic variables
for i in {1..5}; do
pet="pet$i"
declare "sentence$i=$intro I have a pet ${!pet} at home"
done
# Just reading dynamic variables
for i in {1..5}; do
sentence="sentence$i"
echo "${!sentence}"
done
echo
echo "Again, but reading regular variables:"
echo $sentence1
echo $sentence2
echo $sentence3
echo $sentence4
echo $sentence5
输出:
你知道吗,我家里有一只宠物猫
你知道吗,我家里有只宠物鸡
你知道吗,我家里有一头宠物牛
你知道吗,我家里有一只宠物狗
你知道吗,我家里有只宠物猪
同样,但是读取的是常规变量:
你知道吗,我家里有一只宠物猫
你知道吗,我家里有只宠物鸡
你知道吗,我家里有一头宠物牛
你知道吗,我家里有一只宠物狗
你知道吗,我家里有只宠物猪
将两个评分较高的答案结合成一个完整的例子,希望有用且不言自明:
#!/bin/bash
intro="You know what,"
pet1="cat"
pet2="chicken"
pet3="cow"
pet4="dog"
pet5="pig"
# Setting and reading dynamic variables
for i in {1..5}; do
pet="pet$i"
declare "sentence$i=$intro I have a pet ${!pet} at home"
done
# Just reading dynamic variables
for i in {1..5}; do
sentence="sentence$i"
echo "${!sentence}"
done
echo
echo "Again, but reading regular variables:"
echo $sentence1
echo $sentence2
echo $sentence3
echo $sentence4
echo $sentence5
输出:
你知道吗,我家里有一只宠物猫
你知道吗,我家里有只宠物鸡
你知道吗,我家里有一头宠物牛
你知道吗,我家里有一只宠物狗
你知道吗,我家里有只宠物猪
同样,但是读取的是常规变量:
你知道吗,我家里有一只宠物猫
你知道吗,我家里有只宠物鸡
你知道吗,我家里有一头宠物牛
你知道吗,我家里有一只宠物狗
你知道吗,我家里有只宠物猪
尽管这是一个老问题,但我在获取动态变量名时仍然遇到了一些困难,同时避免使用eval (evil)命令。
用declare -n解决了这个问题,它创建了一个动态值的引用,这在CI/CD进程中特别有用,其中CI/CD服务所需的秘密名称直到运行时才知道。方法如下:
# Bash v4.3+
# -----------------------------------------------------------
# Secerts in CI/CD service, injected as environment variables
# AWS_ACCESS_KEY_ID_DEV, AWS_SECRET_ACCESS_KEY_DEV
# AWS_ACCESS_KEY_ID_STG, AWS_SECRET_ACCESS_KEY_STG
# -----------------------------------------------------------
# Environment variables injected by CI/CD service
# BRANCH_NAME="DEV"
# -----------------------------------------------------------
declare -n _AWS_ACCESS_KEY_ID_REF=AWS_ACCESS_KEY_ID_${BRANCH_NAME}
declare -n _AWS_SECRET_ACCESS_KEY_REF=AWS_SECRET_ACCESS_KEY_${BRANCH_NAME}
export AWS_ACCESS_KEY_ID=${_AWS_ACCESS_KEY_ID_REF}
export AWS_SECRET_ACCESS_KEY=${_AWS_SECRET_ACCESS_KEY_REF}
echo $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY
aws s3 ls