lab*_*nth 24 unix linux syntax bash
Bash中标识符的语法规则是什么,特别是函数和变量名?
我写了一个Bash脚本并在Ubuntu,Debian,Red Hat 5和6上的各种版本的Bash上测试了它,甚至是一个旧的Solaris 8盒子.脚本运行良好,所以发货了.
然而,当用户在SUSE机器上尝试它时,它给出了"非有效标识符"错误.幸运的是,我猜测函数名中有一个无效字符是正确的.连字符弄乱了它.
事实上,至少在某种程度上经过测试的脚本在另一个Bash或发行版上会有完全不同的行为,这令人不安.我怎么能避免这个?
Tho*_*mas 24
Shell Function Definitions
...
name () compound-command [redirection]
function name [()] compound-command [redirection]
Run Code Online (Sandbox Code Playgroud)
name
在其他地方定义:
name A word consisting only of alphanumeric characters and under?
scores, and beginning with an alphabetic character or an under?
score. Also referred to as an identifier.
Run Code Online (Sandbox Code Playgroud)
所以连字符无效.然而,在我的系统上,他们确实工作......
$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
Run Code Online (Sandbox Code Playgroud)
命令标识符和变量名称具有不同的语法.变量名称仅限于字母数字字符和下划线,不以数字开头.另一方面,命令名可以是任何不包含bash元字符的东西(即便如此,它们也可以被引用).
在bash中,函数名称可以是命令名称,只要它们被解析为没有引号的WORD即可.(除此之外,由于某种原因,它们不能是整数.)但是,这是一个bash扩展.如果目标机器正在使用其他shell(例如破折号),则它可能不起作用,因为Posix标准shell语法仅在函数定义表单中允许"NAME"(并且还禁止使用保留字).
问题是关于"规则",它已经以两种不同的方式回答,每种方式在某种意义上都是正确的,这取决于你想要称之为"规则"的东西.只是为了充实@罗杰斯国际商品指数的点,你可以推约在功能名称中的任何字符,我写了一个小bash脚本来尝试 检查每一个可能的(0-255)字符作为函数的名称,以及作为第二个字符功能名称:
#!/bin/bash
ASCII=( nul soh stx etx eot enq ack bel bs tab nl vt np cr so si dle \
dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us sp )
for((i=33; i < 127; ++i)); do
printf -v Hex "%x" $i
printf -v Chr "\x$Hex"
ASCII[$i]="$Chr"
done
ASCII[127]=del
for((i=128; i < 256; ++i)); do
ASCII[$i]=$(printf "0X%x" $i)
done
# ASCII table is now defined
function Test(){
Illegal=""
for((i=1; i <= 255; ++i)); do
Name="$(printf \\$(printf '%03o' $i))"
eval "function $1$Name(){ return 0; }; $1$Name ;" 2>/dev/null
if [[ $? -ne 0 ]]; then
Illegal+=" ${ASCII[$i]}"
# echo Illegal: "${ASCII[$i]}"
fi
done
printf "Illegal: %s\n" "$Illegal"
}
echo "$BASH_VERSION"
Test
Test "x"
# can we really do funky crap like this?
function [}{(){
echo "Let me take you to, funkytown!"
}
[}{ # why yes, we can!
# though editor auto-indent modes may punish us
Run Code Online (Sandbox Code Playgroud)
我实际上跳过NUL(0x00),因为这是一个字符bash可能反对在输入流中查找.该脚本的输出是:
4.4.0(1)-release
Illegal: soh tab nl sp ! " # $ % & ' ( ) * 0 1 2 3 4 5 6 7 8 9 ; < > \ ` { | } ~ del
Illegal: soh " $ & ' ( ) ; < > [ \ ` | del
Let me take you to, funkytown!
Run Code Online (Sandbox Code Playgroud)
请注意bash愉快地让我命名我的函数"[} {".可能我的代码不够严谨,无法提供实际合法性的确切规则,但它应该说明可能的滥用方式.我希望我能将这个答案标记为"仅限成熟观众".
归档时间: |
|
查看次数: |
8771 次 |
最近记录: |