Bash脚本无法解释输入

时间:2013-06-20 01:52:08

标签: bash ssh rsync

我写了一个bash脚本,它在我的家庭服务器上传文件。它使用applescript从文件夹操作脚本激活。设置是我桌面上的文件夹名为place_on_server。它应该有一个内部文件结构,就像我想写的文件夹一样:/ var / www / media / 用法是这样的:

  • 如果目录等添加到place_on_server:./ upload DIR等
  • 如果目录目录:etc / movies ./upload DIR等电影//等等
  • 如果文件到place_on_server:./ upload F file.txt
  • 如果文件存放在place_on_server ./upload F等文件中.txt //等等

用于创建一个应该执行如下命令的目录:

ssh root@192.168.1.1<<EOF
cd /var/www/media/wherever
mkdir newdirectory
EOF

和文件放置:

rsync -rsh='ssh -p22' file  root@192.168.1.1:/var/www/media/wherever

脚本:

#!/bin/bash
addr=$(ifconfig -a | ./test)
if ($# -le "1")
then
    exit
elif ($1 -eq "DIR")
then
    f1="ssh -b root@$addr<<EOF"
    list = "cd /var/www/media\n"
    if($# -eq "2")
    then
        list=list+"mkdir $2\nEOF\n"
    else
        num=2
        i=$(($num))
        while($num < $#)
        do
            i=$(($num))
            list=list+"mkdir $i\n"
            list=list+"cd $i\n"
            $num=$num+1
        done
    fi
    echo $list
elif ($1 -eq "F")
then
    #list = "cd /var/www/media\n"
    f2="rsync -rsh=\'ssh -p22\' "
    f3 = "root@$addr:/var/www/media"
    if($# -eq "2")
    then
        f2=f2+$2+" "+f3
    else
        num=3
        i=$(($num))
        while($num < $#)
        do
            i=$(($num))
            f2=f2+"/"+$i
            $num=$num+1
        done
        i=$(($num))
        f2=f2+$i+" "+$f3
    fi
    echo $f2
fi
exit

输出:

(prompt)$ ./upload2 F SO test.txt
./upload2: line 3: 3: command not found
./upload2: line 6: F: command not found
./upload2: line 25: F: command not found

因此,您可以看到我在处理输入时遇到问题。自从我做了bash以来已经有一段时间了。从一开始就没有广泛的。寻找我的问题的解决方案,但也建议。提前谢谢。

2 个答案:

答案 0 :(得分:2)

  1. 要进行比较,请使用[[ .. ]]( .. )用于在子shell中运行命令
  2. 请勿使用-eq进行字符串比较,请使用=
  3. 请勿使用<进行数值比较,请使用-lt
  4. 要附加值f2="$f2$i $f3"
  5. 要添加换行符,请在双引号之外使用$'\n',或在其中使用文字换行符。
  6. 你总是需要对字符串中的变量使用“$”来引用它们,否则你会得到文字字符串。
  7. 您无法在分配中使用=周围的空格
  8. 您无法在分配
  9. 中的变量名称前使用$
  10. 要进行算术,请使用$((..))result=$((var1+var2))
  11. 对于间接引用,例如$4获取n=4,请使用${!n}
  12. 要防止分词删除换行符,请在echo "$line"
  13. 中引用双引号变量

    考虑编写较小的程序并在构建之前检查它们是否有效。

    以下是我编写脚本的方法(稍微缺乏参数检查):

    #!/bin/bash
    addr=$(ifconfig -a | ./test)
    if [[ $1 = "DIR" ]]
    then
      shift
      ( IFS=/; echo ssh "root@$addr" mkdir -p "/var/www/media/$*"; )
    elif [[ $1 = "F" ]]
    then
      shift
      last=$#
      file=${!last}
      ( IFS=/; echo rsync "$file" "root@$addr:/var/www/media/$*" )
    else
      echo "Unknown command '$1'"
    fi
    

    $*为您提供由$IFS中第一个字符分隔的所有参数,我用它来构建路径。这是输出:

    $ ./scriptname DIR a b c d
    ssh root@somehost mkdir -p /var/www/media/a/b/c/d
    $ ./scriptname F a b c d somefile.txt
    rsync somefile.txt root@somehost:/var/www/media/a/b/c/d/somefile.txt
    

    删除实际执行的回声。

答案 1 :(得分:2)

脚本的主要问题是条件语句,例如

if ($# -le "1")

尽管在其他语言中可以做到这一点,但在Bash中这实际上是说,在子shell中执行命令行$# -le "1",并将其退出状态用作条件。

  • 在您的情况下,扩展为3 -le "1",但命令3不存在,这会导致错误消息
      

    ./ upload2:第3:3行:找不到命令

最接近的有效语法是

if [ $# -le 1 ]

这是主要问题,that other guy's post中还详述并解决了其他问题。

最后一件事,当您为变量赋值时,例如

f3 = "root@$addr:/var/www/media"

不要在=周围留出空间。上述语句将被解释为“运行命令f3="root@$addr:/var/www/media"作为参数”。