我如何将此bash脚本转换为纯bourne-shell?

时间:2014-06-21 01:09:45

标签: bash sh

我不熟悉这两种语言,所以我需要一些帮助来确定这个脚本的哪些部分包含" bashisms"或纯bourne-shell解释器可能出错的仅bash语法。

#!/bin/sh
RUNDIR=".run.%SSH_LONG_ID%"
TMPDIR="/tmp/$RUNDIR"

mkdir $TMPDIR
cd $TMPDIR

####################
# Create 'stub2' script
####################

sed 's/^   //' >stub2 << 'MARKITEIGHTDUDE'
   #!/bin/sh
   #

   TMPDIR=`pwd`
   touch running
   sh command
   echo $?
   cd $TMPDIR
   rm -f running
MARKITEIGHTDUDE

####################
# Create 'command' script
####################

sed 's/^   //' >command << 'MARKITEIGHTDUDE'
   #!/bin/sh
   #
   TMPDIR=`pwd`
   %SNCCOMMAND%
MARKITEIGHTDUDE

####################
# Create 'complete' script
####################

sed 's/^   //' >complete << 'MARKITEIGHTDUDE'
   #!/bin/sh
   #

   if [[ $0 == '/'* ]]; then
           TMPDIR="`dirname $0`"
   else
           TMPDIR="`pwd`"/"`dirname $0`"
   fi

   STATUS=`tail -n 1 $TMPDIR/nohup.out`
   sed '$d' < $TMPDIR/nohup.out > $TMPDIR/nohup.out2
   mv $TMPDIR/nohup.out2 $TMPDIR/nohup.out
   cat $TMPDIR/nohup.out
   rm -f $TMPDIR/nohup.out
   rm -f $TMPDIR/stub2
   rm -f $TMPDIR/complete
   rm -f $TMPDIR/command
%ADDITIONALFILES_REMOVE%
   rmdir $TMPDIR
   exit $STATUS
MARKITEIGHTDUDE

####################
# Create additional scripts
####################

%ADDITIONALFILES_ADD%

##

RESULT=`nohup sh stub2 1>$TMPDIR/nohup.out 2>$TMPDIR/nohup.out2 3>/dev/null &`
sleep 1
echo "sncrun:$RUNDIR"
exit 0

我认为[[]]语法只是bash但是我还缺少什么?

3 个答案:

答案 0 :(得分:1)

[[ ]]测试是我看到的唯一基础,但在posix-shell兼容的脚本中替换它并不是一件容易的事。我看到的两个选项是使用case

case "$0" in
    "/"*)
        TMPDIR="`dirname $0`" ;;
    *)
        TMPDIR="`pwd`"/"`dirname $0`" ;;
esac

...或者在shell扩展中使用稍微奇怪的匹配技巧:

if [ "${0#/}" != "$0" ]; then

这样做的方式是"${0#/}"扩展为$0,但有一个领先的&#34; /&#34;删除(如果有)。然后,它只与"$0"进行比较,如果它不同(!=),则$0必须以&#34; /&#34;开头。

正如Aleks-Daniel Jakimenko所指出的那样,有很多变量引用没有被引用,这在某些情况下可能会造成麻烦(例如文件名中的空格)。解决这个问题非常重要,因为必须在反引号之间转义双引号。如果你关心这个,我建议先用$( )取代所有的反引号(这是posix标准,所以它应该是可移植的)。然后你可以干净地嵌套双引号,就像在TMPDIR="$(pwd)/$(dirname "$0")"中一样(注意:我也将/留在双引号内 - 这实际上并不重要,我发现它更容易读取)。

BTW2,有没有理由在结尾附近捕获nohup ed命令的(不存在的)输出?也就是说,为什么不替换

RESULT=`nohup sh stub2 1>$TMPDIR/nohup.out 2>$TMPDIR/nohup.out2 3>/dev/null &`

只是

nohup sh stub2 1>$TMPDIR/nohup.out 2>$TMPDIR/nohup.out2 3>/dev/null &

答案 1 :(得分:0)

现在有点不清楚,“纯粹的Bourne shell”这样的东西甚至存在。您可以将shebang写为/ bin / sh以强制执行“仅限sh”模式,但实际上它只是强制POSIX合规性。但是,这可能会在一般意义上为您提供所需的内容。

有关详细信息,请查看以下两个来源:

http://www.network-theory.co.uk/docs/bashref/BashPOSIXMode.html

https://unix.stackexchange.com/questions/44836/when-sh-is-a-symlink-to-bash-or-dash-bash-limits-itself-to-posix-compliance-so

答案 2 :(得分:-3)

立即脱颖而出的唯一变化是:

if [[ $0 == '/'* ]]; then

更改为

firstchar=`sed -e "s/\/.*$/\//" <<< $0`
if test "$firstchar" = "/"; then

Difference with borne shell

仔细检查