我不熟悉ksh脚本,我想将其转换为有效的ksh脚本。
egrep "^[^#;]" /etc/security/user |
while read x;
do
if [[ $x == '^\S+:' ]]; then
section=$x;
fi;
if [[ $section == 'nobody:' ]]; then
echo $x;
fi;
done
/ etc / security / user的内容如下:
sys:
admin = true
expires = 0101000070
login = false
rlogin = false
adm:
admin = true
login = false
rlogin = false
nobody:
admin = true
expires = 0101000070
login = false
rlogin = false
invscout:
admin = true
我的目标是能够指定我想从哪个用户获取参数,并让它只回显用户的参数。例如,如果我指定" nobody"在命令中shell应该输出:
admin = true
expires = 0101000070
login = false
rlogin = false
我理解ksh不支持模式匹配正则表达式,就像bash一样,但是在成功转换命令时遇到了麻烦。任何和所有的帮助将不胜感激。没有和空格的命令如下:
grep "^[^#;]" /etc/security/user | while read x; do if [[ $x =~ '^\S+:' ]]; then section=$x; fi; if [[ $section == 'nobody' ]]; then echo $x; fi; done
答案 0 :(得分:3)
问题根本不是针对ksh的。以下在ksh(版本93u + 2012-08-01)中是完全合法的,并且也是 bash中的最佳实践代码(或者至少接近它;可能会移动grep
进程替换为一种增强,可以在两个shell中增加值。)
#!/usr/bin/env ksh
section_re='^[^[:space:]]+:'
grep -v '^[#;]' /etc/security/user |
while IFS= read -r x; do
if [[ $x =~ $section_re ]]; then
section=$x
fi
if [[ $section = 'nobody:' ]]; then
echo "$x"
fi
done
==
不是test
的POSIX标准化参数,用于字符串比较。使用=
代替,甚至在非POSIX shell上,以确保良好的习惯(将转移到POSIX平台)。=
和==
不执行正则表达式测试;该运算符为=~
。=~
的右手参数必须不加引号,以防止将其视为文字。将正则表达式放在一个变量中,并将该变量扩展为未引用的变量,是实现此目的的最佳实践可移植机制。\S
在POSIX扩展正则表达式中无效,这是ksh 或 bash中=~
右侧保证唯一支持的语法echo "$x"
,而不是echo $x
。-r
参数read
,除非您明确要求它抑制的行为(除非配对,否则从输入中删除文字反斜杠,将其视为使read
消耗多行(如果这样的反斜杠)是最后一个角色。)IFS
时清除read
(因此,使用IFS= read
),除非您明确要求修剪前导和尾随空格的行为; 或如果您需要IFS
来区分同时读取的多个字段之间的边界。当使用ksh93和您提供的样本输入文件运行时,上述输出为:
nobody:
admin = true
expires = 0101000070
login = false
rlogin = false
(包括nobody:
在输出中也是预期的,原因很明显,如果有人读取代码;在continue
之后紧跟section=$x
之后,在同一if
内},如果 不受欢迎的话。)
将来,请在此处提问之前通过http://shellcheck.net/运行您的代码。