2015-01-29 2 views
1

Я хочу выполнить команду echo перед ее выполнением. Эта команда заменяет строку 'PROJECT_NAME' 'Hello world' в файле file.yaml.Как выполнить команду echo перед ее выполнением

PROJECT_NAME="Hello world" 
CMD="replace.py 'PROJECT_NAME' '${PROJECT_NAME}' file.yaml" 
echo "${CMD}" 
${CMD} 

Каков правильный способ процитировать эту строку, чтобы команда выполнялась, и эхо отображает команду?

Обратите внимание, что значение переменной $ {PROJECT_NAME} содержит пробелы, а replace.py занимает ровно 3 аргумента.

Я попытался убежать от всех котировок (\ ') и знаков доллара (\ $). Я попытался заменить одиночные кавычки (') на двойные кавычки (").

С некоторыми цитатами он будет рассматривать каждое слово в« Hello world »как отдельный аргумент arg, так что replace.py захлопнет« мир », не будучи имя файла, которое он ожидает.

Я прочитал http://mywiki.wooledge.org/BashFAQ/050, но все еще не могу понять. Я предпочитаю не дублировать команду или использовать set -x (потому что он печатает набор + x при использовании этого, чтобы отключить его).

ответ

1

Правильный способ сохранить командную строку и выполнить ее позже можно сделать 2-мя способами:

  1. Использование BASh массивов
  2. Используйте функцию BASH

1. Используя массив BASH:

PROJECT_NAME="Hello world" 
cmd=("replace.py" "PROJECT_NAME" "$PROJECT_NAME" "file.yaml") 
printf "%q " "${cmd[@]}"; echo 
"${cmd[@]}" 

Теперь запустите его как:

bash ./script.sh 
replace.py PROJECT_NAME Hello\ world file.yaml 

Примечание экранирование пространства %q из printf. Вы можете запустить эту командную строку из оболочки непосредственно также проверить его снова, т.е.

replace.py PROJECT_NAME Hello\ world file.yaml 

2.Использование функции:

#!/bin/bash 

PROJECT_NAME="Hello world" 
cmd() { 
    set -x 
    replace.py "PROJECT_NAME" "$PROJECT_NAME" "file.yaml" 
    set +x 
} 

cmd 

Теперь запустите его как:

./script.sh 

и вы получите аналогичный результат:

+ replace.py PROJECT_NAME 'Hello world' file.yaml 
... 
... 
set +x 

Вы можете запустить эту командную строку также:

replace.py PROJECT_NAME 'Hello world' file.yaml 
1

Одна возможность состоит в том, чтобы использовать массив вместо простой строки, а затем использовать формат printf «s %q повторно добавить кавычки и/или ускользает, где это необходимо:

PROJECT_NAME="Hello world" 
CMD=(replace.py 'PROJECT_NAME' "${PROJECT_NAME}" file.yaml) 
printf "%q " "${CMD[@]}"; printf "\n" 
"${CMD[@]}" 

Обратите внимание, что это может не использовать тот же метод цитирования/экранирования, который вы использовали при создании массива; например, я попытался выше и напечатал:

replace.py PROJECT_NAME Hello\ world file.yaml 

что эквивалентно:

replace.py 'PROJECT_NAME' "Hello world" file.yaml 

... просто другой способ написания той же команды.

+0

Похоже, вы говорите ther e нет простого способа (кроме set -x), чтобы избежать команды, которая не загромождает и будет очевидна для большинства читателей. В этом случае я бы пошел с set -x. Благодарю. – dougkramer