English 中文(简体)
替换和新的实践从上海到Bash是什么?
原标题:
  • 时间:2009-03-27 18:08:06
  •  标签:

人做了很多sh脚本20年前,现在回来,我发现我使用技术,被认为是过时了。我应该花时间去阅读“新”,但我t和它年代不是非常有效。例子:

 Instead of             use 

 tmpfile=/tmp/me$$      tmpfile=`mktemp`

 [ ]                     [[ ]]

是什么改变你认为重要的是比较原始的Bourne shell的抨击?

最佳回答

味道:

  • 忘记<强>(< / >强,学习<强>[[< /强>:

    • No wordsplitting or pathname expansion happens on unquoted variables in [[.
    • You can use = to do glob pattern matching: [[ $foo = *.txt ]] (foo ends with .txt)
    • You can use =~ to do ereg pattern matching: ereg= .*.txt ; [[ $foo =~ $ereg ]]
    • You can use &&, || and ( ) inside the test: [[ $bar && ( $foo = *.txt || $foo = *.bar ) ]]
    • Gotcha: RHS of = is considdered a glob pattern: bar= I pinch?? ; [[ "I pinched" = $bar ]] # test passes.
  • 使用(())的数值。

如。

(( ++count ))
(( $# )) || { echo "Expected an argument to the script." >&2; exit 1; }
  • Some lovely IO operators, such as <(), <<<, etc.

如。

read filesize _ < <(wc -c myfile)
openssl base64 <<< "Bar!" # as opposed to the more expensive: echo "Bar!" | openssl base64
content=$(<file) # as opposed to the more expensive: content=$(cat file)
  • Forget deprecated syntax, such as `` . The new syntax often has imporant advantages. $() nests easily (just you try to nest `` sanely), quoting inside $() works easily (again, it s a mess in `` ), etc.

如。

rm "$(grep -l foo <<< "$(</my/file.list)")"
  • Arrays, arrays, arrays. Whenever you need to keep multiple strings (like filenames!), keep them in arrays. Do not keep them in a single string that uses some kind of delimitor to separate your separate strings, this method is always flawed.

如。

files=(/foo/*); for file in "${files[@]}"; do pinch "$file"; done

更多信息,看看下面的地方。他们可能是最为有用的和可信赖的Bash资源:

问题回答

这可能不是直接回答你的问题,但我认为这些“陷阱”来自上海习惯:

< a href = " http://wooledge.org: 8000 / BashPitfalls”rel = " nofollow noreferrer " > http://wooledge.org: 8000 / BashPitfalls < / >

脚本,除非有特殊原因,否则,伯恩我限制自己的结构。他们最大限度地移植,应该运行在系统使用bash, ksh,甚至sh作为他们的默认shell。

我发现任何实际性能差异最小(秒表计时);如果性能是重要的和有限的壳,我把时序要求严格的编译语言。更现代的外壳的额外的功能很好,我使用它们交互或者临时快速脚本。如果我要分发和维护的代码,但是,我已经发现,忽略了扩展可以节省我的时间和精力。

如果你熟悉Bourne shell语法,并可以使脚本使用Bourne shell的做你想做的事,然后用扩展不打扰。

而不是

tmpfile=`mktemp`

使用

tmpfile=$(mktemp) 

一般推荐的做法(最好巢)

我还指出bash4.0 s释放这种情况在一些脚本。

foo="$( some   
          multiline 
          command  in a string)"

The problem since 4.0 I ve been finding is that newlines need to be explicitly escaped in that case too, so

foo="$( some  
          multiline 
          command  in a string)"

建议。

这里已经添加:

字符串maipulation在现代壳更好。与老上海,<代码> $ {var # #模式}< /代码>和<代码> $ {var % %模式}< /代码> contructs,但是bash和ksh93(和其他不常见的贝壳)操作符将字符串替换(如<代码> $ {var /源/替换}> < /代码)。

extglob正则表达式支持也相当方便,虽然不是新的,但通常由老式的shell程序员没有得到充分利用

[[ "$str" = @(+([a-z])?([0-9])) ]]

匹配字符串的所有字母数字或字母数字以一个数字。我用所有的时间在ksh88……

然后s变量变量(<代码> var =你好;你好=你好;echo $ $ var > < /代码)和数组足以实际上是有用的。数组是那些老派壳的另一个开发人员常常未充分使用,部分因为1024元素的限制,存在于现代的贝壳,它们支持至少4096的元素,和他们中的大多数支持关联数组(perl称之为散列)。





相关问题
热门标签