循环使用命令在BASH中打印和执行

时间:2009-07-29 22:03:27

标签: bash

在BASH,我想做这样的事情:

#!/bin/bash                                                                     

HOST="blah"
USER="foo"
REMOTE_ROOT="${HOST}:~${USER}/"

REP_NAME=`basename $1`
TARGET_NAME="${REP_NAME}.git"

CMD1="git clone --bare $1 $TARGET_NAME"
CMD2="touch ${TARGET_NAME}/git-daemon-export-ok"
CMD3="scp -r $TARGET_NAME $REMOTE_ROOT"
CMD4="rm -rf $TARGET_NAME"

for i in {1..4}
do
  CMD="${CMD${i}}"
  echo "$CMD"
  `$CMD`
done

也就是说,我想遍历一个命令列表,显示正在执行的命令,然后执行它。

我不知道如何进行双重解除引用(CMD =“$ {CMD $ {i}}”在BASH中不合法。

或者,我很乐意做类似的事情:

for CMD in "CMD1 CMD2 CMD3 CMD4"
do
  echo $$CMD
done

但当然这也不是正确的语法。

6 个答案:

答案 0 :(得分:3)

CMDS[1]="git clone --bare $1 $TARGET_NAME"
CMDS[2]="touch ${TARGET_NAME}/git-daemon-export-ok"
CMDS[3]="scp -r $TARGET_NAME $REMOTE_ROOT"
CMDS[4]="rm -rf $TARGET_NAME"

# ...

for x in 1 2 3 4
do
    ${CMDS[x]};
done

答案 1 :(得分:1)

您可以将您的CMD改为array吗?

答案 2 :(得分:1)

你想要$ {!参数}语法,至少在bash中工作。 e.g。

#!/bin/sh

CMD1="ls"
CMD2="pwd"

for CMD in {CMD1,CMD2} ; do
    echo ${!CMD}
    ${!CMD}
done

答案 3 :(得分:0)

要做你想要的事情:

for i in 1 2 3 4; do
    eval cmd='$'CMD$i
    echo $cmd
    eval $cmd
done

对于备用解决方案,您可以使用eval:

for CMD in CMD1 CMD2; do
    eval '$'$CMD
done

答案 4 :(得分:0)

你们都忘记了seq(1)。它需要三个参数:seq START INTERVAL END并生成一个新的行分隔列表(包括)START和END,所以你可以这样做:

for i in `seq 1 1 4`
do
   echo...

也:

如果在host:之后给出相对路径,则假定它是登录用户的主目录。所以你可以这样做:

REMOTE_ROOT="${HOST}:"

答案 5 :(得分:0)

这更像是一个调试/故障排除功能,并没有完全回答你的问题,但我发现它很有用:

#!/bin/bash

# Enable command echoing
set -x 

pwd
uname -a

# Disable command echoing
set +x

echo 'Command echoing off now'

示例运行:

~$ ./foo.sh 
+ pwd
/home/jason
+ uname -a
Linux jpc 2.6.26-2-amd64 #1 SMP Sun Jun 21 04:47:08 UTC 2009 x86_64 GNU/Linux
+ set +x
Command echoing off now
~$ 

或者如果您有类似的文件:

#!/bin/bash

pwd
uname -a

您可以使用bash -x执行相同的操作,而无需修改文件:

~$ bash -x ./bar.sh 
+ pwd
/home/jason
+ uname -a
Linux jpc 2.6.26-2-amd64 #1 SMP Sun Jun 21 04:47:08 UTC 2009 x86_64 GNU/Linux
~$