我正在编写一个 Git Bash 实用程序,它将项目文件夹从一个位置复制到另一个位置。用户可能希望将项目复制到多个目标,但每次执行脚本只允许一个位置。到目前为止的逻辑是这样的 -
#!/bin/bash
# declare and initialize variables
source="/z/files/development/xampp/code/htdocs/Project7"
targets[0]="/z/files/development/xampp/code/htdocs/test/$(date +'%Y_%m_%d')"
targets[1]="/c/users/knot22/desktop/temp_dev/$(date +'%Y_%m_%d')"
# display contents of variables to user
echo "source " $source
echo -e "\nchoice \t target location"
for i in "${!targets[@]}"; do
echo -e "$i \t ${targets[$i]}"
done
echo
# prompt user for a target
read -p "Enter target's number for this copy operation: " target
到目前为止,一切都很好。接下来我想编写一个if
语句来检查用户输入的值是否target
是targets
.在 PHP 中它将是array_key_exists($target, $targets)
. Bash 中的等价物是什么?
答案1
您可以使用以下命令检查数组元素是否不为空/空:
expr='^[0123456789]+$'
if [[ $target =~ $expr && -n "${targets[$target]}" ]]; then
echo yes
else
echo no
fi
您还必须检查响应是否为整数,因为人们可以使用字符串回复读取提示,该字符串的计算结果为零,从而为您提供数组中的第一个元素。
您可能还想考虑使用选择这里:
#!/bin/bash
# declare and initialize variables
source="/z/files/development/xampp/code/htdocs/Project7"
targets[0]="/z/files/development/xampp/code/htdocs/test/$(date +'%Y_%m_%d')"
targets[1]="/c/users/knot22/desktop/temp_dev/$(date +'%Y_%m_%d')"
select i in "${targets[@]}" exit; do
[[ $i == exit ]] && break
echo "$i which is number $REPLY"
done
答案2
TL;DR 这个答案是错误的,但我解释了原因。
我写:
你可以使用
-v
if [[ -v targets[$target] ]]; then ...
但那是错误的。
在数字索引数组中,索引被计算为算术表达式。在算术表达式中,“裸”字符串被处理为外壳变量如果变量为空或未设置,则将其处理为值零。
演示:
targets=(zero one two)
target=2
[[ -v targets[target] ]] && echo "${targets[target]}" || echo n
# ==> two
target="x"
[[ -v targets[target] ]] && echo "${targets[target]}" || echo n
# ==> zero
但如果有一个变量具有相同的姓名作为价值的$target
,那么:
x=1
[[ -v targets[target] ]] && echo "${targets[target]}" || echo n
# ==> one