Я провел последний час или около того, пытаясь написать довольно простой сценарий bash, и я никогда не чувствовал себя настолько глупым.

Итак, у меня есть список строк (которые являются спецификациями селектора пакетов для менеджера пакетов, если это имеет значение), которые могут содержать звездочки. Мне нужно создать командную строку, сохраняя эти звездочки, а затем вызвать программу. Вот моя наивная попытка:

xs="foo/bar */*"

xs_cmd=""
for x in $xs; do
  xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd

Мне нужно, чтобы echo вызов был эквивалентен

echo   -0 foo/bar    -0 '*/*' 

который выводит -0 foo/bar -0 */* .

PS На самом деле первая строка немного сложнее: xs="$some foo/bar */* $(get_others)" .


Если вы запустите этот скрипт в каталоге, содержащем a/b , вы получите вместо этого -0 foo/bar -0 a/b .

Когда я меняю последнюю строку на

echo "$xs_cmd"  # note the quotes

Я получаю -0 foo/bar -0 a/b и, во-первых, это не то, что я хочу, так как теперь я вызываю echo с одним аргументом, и, кроме того, это говорит мне, что расширение происходит раньше, вероятно, в for цикла.

Но я не могу изменить for линии , потому что

for x in "$xs"; do  # note the quotes

только цикл будет повторяться только один раз: -0 foo/bar */* (есть один -0), поэтому добавление этих кавычек не является опцией наверняка.

Теперь, если я вернусь к исходному сценарию и заменим первую строку на

xs="foo/bar '*/*'"  # note additional single quotes

Я получаю -0 foo/bar -0 '*/*' (одинарных кавычек не должно быть).

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

2 ответа2

0

В зависимости от того, чего вы пытаетесь достичь, вам нужно процитировать эти */*:

xs="foo/bar '*/*'" #!

xs_cmd=""
for x in $xs ; do
    xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd
eval echo $xs_cmd
eval "echo $xs_cmd"

или используйте массивы, или оба:

xs=("foo/bar" "*/*") #!

xs_cmd=""
for x in "${xs[@]}"; do
    xs_cmd="$xs_cmd  -0 '$x' " #!
done

echo "$xs_cmd"
eval "echo $xs_cmd"
0

Я использовал ваш оригинальный скрипт, но с одинарными кавычками в первой строке (только), и он работал так, как я думаю, вы хотите (-0 перед каждым путем к файлу):-

xs='foo/bar */*'

xs_cmd=""
for x in $xs; do
  xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd

Вероятно, вы обнаружите проблемы, когда будете использовать его, если в любом из путей к файлам есть пробелы. Если это так, измените команду в цикле на:-

  xs_cmd="$xs_cmd  -0 \"$x\" "

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .