Циклические команды для печати и выполнения в BASH - PullRequest
2 голосов
/ 30 июля 2009

В 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 ]

3 голосов
/ 30 июля 2009
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 голос
/ 30 июля 2009

Вам нужен синтаксис $ {! Parameter}, работает в bash по крайней мере. например,

#!/bin/sh

CMD1="ls"
CMD2="pwd"

for CMD in {CMD1,CMD2} ; do
    echo ${!CMD}
    ${!CMD}
done
1 голос
/ 30 июля 2009

Не могли бы вы вместо этого поместить свои CMD в массив ?

0 голосов
/ 30 июля 2009

Это больше функция отладки / устранения неполадок, и она не совсем отвечает на ваш вопрос, но я считаю ее полезной:

#!/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
~$ 
0 голосов
/ 30 июля 2009

вы все забыли seq (1). он принимает три аргумента: seq START INTERVAL END и создает новый список с разделителями строк между (включительно) START и END, так что вы можете сделать:

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

также:

если после host: указан относительный путь, предполагается, что он является домашним каталогом пользователя входа в систему. так что вы можете просто сделать:

REMOTE_ROOT="${HOST}:"
0 голосов
/ 30 июля 2009

Чтобы сделать то, что вы хотите использовать:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...