#!/bin/bash
if [ $# -gt 0 ]; then
snum=( $@ )
echo $snum
fi
Run Code Online (Sandbox Code Playgroud)
./testscript.sh 1234 4568
当我运行像The output of echo command is only 这样的脚本时1234,所以我想我没有构建所有位置参数的数组?
#!/bin/bash
if [ $# -gt 0 ]; then
snum="$@"
echo $snum
fi
Run Code Online (Sandbox Code Playgroud)
并运行./testscript.sh 1234 4568
输出是1234 4568
我想知道为什么snum=( $@ )只采用第一个位置参数?
在列表上下文中使用"$@"(包括双引号)来获取单独引用的位置参数列表。
在标量上下文中使用"$*"(包括双引号)将位置参数连接到单个字符串中,并以第一个字符$IFS(通常是空格)作为分隔符。
使用$@不带引号的(如第一个示例中所示)或"$@"在标量上下文中使用(如第二个示例中所示)很少有意义。在bashshell 中,在标量上下文中使用与将第一个字符设置为空格的情况"$@"相同。"$*"$IFS
使用时snum=( "$@" ),您创建数组snum。如果您访问变量为$snum,您将获得数组的第一个元素。实际上,它与访问 相同${snum[0]}。使用"${snum[@]}"为您提供单独引用的元素的列表,其方式与 类似"$@"。使用"${snum[*]}"给你相当于"$*", 但对于数组snum。
snum假设您想从位置参数列表创建一个数组,然后打印该数组(如果它不为空),您可以使用
#!/bin/bash
snum=( "$@" )
if [ "${#snum[@]}" -gt 0 ]; then
printf '%s\n' "${snum[@]}"
fi
Run Code Online (Sandbox Code Playgroud)
snum如果给脚本提供了参数,这将在单独的行上打印 的元素。
运行示例:
bash-5.1$ ./script 1 2 3 "hello world" 4
1
2
3
hello world
4
Run Code Online (Sandbox Code Playgroud)
请注意,该hello world参数被保留为单个参数,如果您忘记了 周围的引号,情况就不会$@是这样。
在单个字符串中打印位置参数列表,以冒号分隔。通过修改字符串在位置参数之间插入冒号$IFS。
#!/bin/bash
IFS=:
snum="$*"
if [ -n "$snum" ]; then
printf '%s\n' "$snum"
fi
Run Code Online (Sandbox Code Playgroud)
这里的区别在于snum现在是单个字符串,而不是元素数组。如果该字符串非空,即如果为脚本提供了至少一个非空参数,则该脚本将输出该字符串。
或者,稍微修改我们的第一个示例以继续用作snum数组,
#!/bin/bash
snum=( "$@" )
if [ "${#snum[@]}" -gt 0 ]; then
IFS=:
printf '%s\n' "${snum[*]}"
fi
Run Code Online (Sandbox Code Playgroud)
运行示例:
bash-5.1$ ./script 1 2 3 "hello world" 4
1:2:3:hello world:4
Run Code Online (Sandbox Code Playgroud)
var=( values )
Run Code Online (Sandbox Code Playgroud)
是数组变量赋值
var=value
Run Code Online (Sandbox Code Playgroud)
是一个标量变量赋值(并且var="$@",var被分配位置参数的空间串联作为一个字符串,因为它是一个标量)
$var数组上的元素扩展为索引 0 的元素,与${var[0]}您需要的数组中的所有元素相同${var[@]},这是从 Korn shell 复制的错误设计。
另请注意:
echo不能用于输出 中的任意数据bash。在这里,您想要:
#! /bin/bash -
print_space_separated() {
local IFS=' '
printf '%s\n' "$*"
}
if [ "$#" -gt 0 ]; then
snum=( "$@" )
print_space_separated "${snum[@]}"
fi
Run Code Online (Sandbox Code Playgroud)
在zshwho 的数组设计比cshof更接近的情况下ksh,您可以这样做:
#! /bin/zsh -
if (( $# > 0 )) {
snum=( $argv )
print -r -- $snum
}
Run Code Online (Sandbox Code Playgroud)
(其print -r本身来自 ksh)
但需要注意的是,即使在该 shell 中的参数扩展时没有 split+glob,保留数组扩展不带引号仍然会删除空元素。要保留它们,您需要 ksh 语法:
#! /bin/zsh -
if (( $# > 0 )) {
snum=( "$@" )
print -r -- "${snum[@]}"
}
Run Code Online (Sandbox Code Playgroud)
(尽管"${snum[@]}"可以缩短为"$snum[@]")。
请注意, invar="$@"或var="${array[@]}",var最终包含一个由位置参数组成的字符串,该位置参数与$IFSin的第一个字符连接zsh,并与 空格连接bash。POSIX 在那里未指定行为,$@仅用于引用和列表上下文中。要获取与可移植的第一个字符连接的位置参数$IFS,请使用"$*"(在列表或非列表上下文中)。
要将数组的元素与任意字符串(而不是 的第一个字符$IFS)连接起来,请在:中使用j参数扩展标志。没有同等的。有。zsh${(j[that-string])array}bashfishstring join -- that-string $array
| 归档时间: |
|
| 查看次数: |
674 次 |
| 最近记录: |