sh/bash/dash/ksh/zsh等Shell脚本
-
wrj20080607
- 帖子: 12
- 注册时间: 2011-12-16 21:56
#1
帖子
由 wrj20080607 » 2021-05-12 0:09
简单的代码如下:
代码: 全选
#!/bin/bash
a[0]='a b'
a[1]='c d'
a[2]='e f'
##define function
function1(){
n=0
for line in $1;
do
let n++
done
echo "function1 is $n"
}
##main1
function1 "${a[*]}"
##loop1
n=0
for line in "${a[@]}";
do
let n++
done
echo "loop1 is $n"
运行后,function1 和loop1 的结果截然不同:
代码: 全选
ubuntu@ubuntu:~$ ./arry_function.sh
function1 is 6
loop1 is 3
很显然,数组a的每一个元素都有空格,在函数function1里面用for循环遍历数组a时,把数组a识别成6个元素;
不在函数里面时,loop1的for循环遍历数组a,识别正确,数组a有3个元素,请问有谁知道这种情况怎么处理吗?谢谢^_^
-
jiandan23
- 帖子: 86
- 注册时间: 2010-12-17 22:31
- 系统: Mint 19.2
#2
帖子
由 jiandan23 » 2021-05-12 10:40
a[0]='a b'
a[1]='c d'
a[2]='e f'
##define function
function1(){
n=0
for line in "$@";
do
let n++
done
echo "function1 is $n"
}
function1 "${a[@]}"
-
wrj20080607
- 帖子: 12
- 注册时间: 2011-12-16 21:56
#3
帖子
由 wrj20080607 » 2021-05-12 15:45
jiandan23 写了: ↑2021-05-12 10:40
a[0]='a b'
a[1]='c d'
a[2]='e f'
##define function
function1(){
n=0
for line in "$@";
do
let n++
done
echo "function1 is $n"
}
function1 "${a[@]}"
非常感谢这个方法很好,论坛果然高手如云啦^_^。
想借楼再问问,如果函数function1 接收几个不同的参数,有几个数组(数组元素都有空格),有普通变量。
比如这样 function1 "${a[@]}" "${b[@]}" $c 这个时候还有办法处理吗?
-
wrj20080607
- 帖子: 12
- 注册时间: 2011-12-16 21:56
#4
帖子
由 wrj20080607 » 2021-05-12 18:11
wrj20080607 写了: ↑2021-05-12 15:45
jiandan23 写了: ↑2021-05-12 10:40
a[0]='a b'
a[1]='c d'
a[2]='e f'
##define function
function1(){
n=0
for line in "$@";
do
let n++
done
echo "function1 is $n"
}
function1 "${a[@]}"
非常感谢这个方法很好,论坛果然高手如云啦^_^。
想借楼再问问,如果函数function1 接收几个不同的参数,有几个数组(数组元素都有空格),有普通变量。
比如这样 function1 "${a[@]}" "${b[@]}" $c 这个时候还有办法处理吗?
根据前面的 jiandan23 给出的思路,我想了一个方法,终于实现了多个数组(元素有空格)作为参数传入函数中:就是把数组a 和数组b 的各自的长度先计算出来,再作为两个参数一起传入函数中,这样就可以在函数中正确读取每一个数组了。
这个方法有点麻烦,如果哪位知道更简单的方法,可以告诉我一下啊,再次感谢各位^_^
顺便贴一下我写的代码,给有需要的人:
代码: 全选
#!/bin/bash
a=('a a' 'b b' 'c c')
b=('d d' 'e e' 'f f')
c='ccc'
##define function
function1(){
n=0
sum1=$1
sum2=$2
for line in "$@";
do
if [ $n -ge 2 ] && [ $n -lt $[sum1+2] ];then
arry1[n-2]=$line
elif [ $n -ge $[sum1+2] ] && [ $n -lt $[sum1+2+sum2] ];then
arry2[n-2-sum1]=$line
fi
let n++
done
echo "The {a} is : ${arry1[@]}"
echo "The {b} is : ${arry2[@]}"
}
##main
sum1=${#a[@]}
sum2=${#b[@]}
function1 $sum1 $sum2 "${a[@]}" "${b[@]}" $c
执行结果为
代码: 全选
ubuntu@ubuntu:~$ ./arry_function.sh
The {a} is : a a b b c c
The {b} is : d d e e f f
-
wrj20080607
- 帖子: 12
- 注册时间: 2011-12-16 21:56
#5
帖子
由 wrj20080607 » 2021-05-12 18:26
再次感谢 jiandan23 解决了我的疑惑 ,通过这个例子,我也大概明白了"${a[@]}"和"${a[*]}"传入函数的区别,类似于"$@"和"$*"
-
astolia
- 论坛版主
- 帖子: 6456
- 注册时间: 2008-09-18 13:11
#6
帖子
由 astolia » 2021-05-12 21:34
wrj20080607 写了: ↑2021-05-12 18:11
根据前面的 jiandan23 给出的思路,我想了一个方法,终于实现了多个数组(元素有空格)作为参数传入函数中:就是把数组a 和数组b 的各自的长度先计算出来,再作为两个参数一起传入函数中,这样就可以在函数中正确读取每一个数组了。
这个方法有点麻烦,如果哪位知道更简单的方法,可以告诉我一下啊,再次感谢各位^_^
可以只传入数组名,然后用eval把数组的内容复制给另外的变量
代码: 全选
a=("1 1" "2 2" "3 3")
b=(a b c d)
f() {
eval 'p1=("${'$1'[@]}")';
eval 'p2=("${'$2'[@]}")';
echo "1st array $1=${p1[@]}, size=${#p1[@]}";
echo "2nd array $2=${p2[@]}, size=${#p2[@]}";
}
f a b
f b a
-
wrj20080607
- 帖子: 12
- 注册时间: 2011-12-16 21:56
#7
帖子
由 wrj20080607 » 2021-05-12 22:58
astolia 写了: ↑2021-05-12 21:34
wrj20080607 写了: ↑2021-05-12 18:11
根据前面的 jiandan23 给出的思路,我想了一个方法,终于实现了多个数组(元素有空格)作为参数传入函数中:就是把数组a 和数组b 的各自的长度先计算出来,再作为两个参数一起传入函数中,这样就可以在函数中正确读取每一个数组了。
这个方法有点麻烦,如果哪位知道更简单的方法,可以告诉我一下啊,再次感谢各位^_^
可以只传入数组名,然后用eval把数组的内容复制给另外的变量
代码: 全选
a=("1 1" "2 2" "3 3")
b=(a b c d)
f() {
eval 'p1=("${'$1'[@]}")';
eval 'p2=("${'$2'[@]}")';
echo "1st array $1=${p1[@]}, size=${#p1[@]}";
echo "2nd array $2=${p2[@]}, size=${#p2[@]}";
}
f a b
f b a
,非常感谢astolia,版主给出的代码果然简洁,一行代码就传递了整个数组。我在上楼还写了个繁琐的循环呢
赶紧在terminal里面查询自己不懂的地方
代码: 全选
eval --help
eval: eval [参数 ...]
将参数作为 shell 命令执行。
将 ARGs 合成一个字符串,用结果作为 shell 的输入,
并且执行得到的命令。
退出状态:
以命令的状态退出,或者在命令为空的情况下返回成功。
从上面的解释看,eval是将那一行参数合成了字符串,用结果作为shell命令执行了一遍
代码: 全选
eval 'p1=("${'$1'[@]}")';
上面这行代码里面,看懂了 $1=a ,但是外面那个小括号()不知道是其什么作用的
-
astolia
- 论坛版主
- 帖子: 6456
- 注册时间: 2008-09-18 13:11
#8
帖子
由 astolia » 2021-05-12 23:01
小括号表示是在定义数组,这句话就是在执行p1=("${a[@]}"),然后把"${a[@]}"展开就成了p1=("1 1" "2 2" "3 3")这样
另外也可以用间接引用/双重引用来代替eval,不过这样的话传入方式也要换种写法。
代码: 全选
a=("1 1" "2 2" "3 3")
b=(a b c d)
f() {
p1=("${!1}");
p2=("${!2}");
echo "1st array $1=${p1[@]}, size=${#p1[@]}";
echo "2nd array $2=${p2[@]}, size=${#p2[@]}";
}
f a[@] b[@]
f b[@] a[@]
-
wrj20080607
- 帖子: 12
- 注册时间: 2011-12-16 21:56
#9
帖子
由 wrj20080607 » 2021-05-12 23:18
astolia 写了: ↑2021-05-12 23:01
小括号表示是在定义数组,这句话就是在执行p1=("${a[@]}"),然后把"${a[@]}"展开就成了p1=("1 1" "2 2" "3 3")这样
另外也可以用间接引用/双重引用的来代替eval,不过这样的话传入方式也要换种写法。
代码: 全选
a=("1 1" "2 2" "3 3")
b=(a b c d)
f() {
p1=("${!1}");
p2=("${!2}");
echo "1st array $1=${p1[@]}, size=${#p1[@]}";
echo "2nd array $2=${p2[@]}, size=${#p2[@]}";
}
f a[@] b[@]
f b[@] a[@]
再次感谢版主astolia
原来如此,终于弄明白了那个小括号的作用了,eval的用法也很强大^_^
后面这个间接引用的方法更加简洁,直接 p1=("${!1}") ; 就行了
shell 编程果然博大精深