Передача аргументов в команду в скрипте Bash с пробелами - PullRequest
11 голосов
/ 21 января 2011

Я пытаюсь передать 2 аргумента команде, и каждый аргумент содержит пробелы, я пытался экранировать пробелы в аргументах, я пытался заключить в одинарные кавычки, я пытался экранировать \ ", но ничего не получится работа.

Вот простой пример.

#!/bin/bash -xv

ARG="/tmp/a b/1.txt"
ARG2="/tmp/a b/2.txt"

ARG_BOTH="\"$ARG\" \"$ARG2\""
cat $ARG_BOTH

Я получаю следующее при запуске:

ARG_BOTH="$ARG $ARG2"
+ ARG_BOTH='/tmp/a\ b/1.txt /tmp/a\ b/2.txt'
cat $ARG_BOTH
+ cat '/tmp/a\' b/1.txt '/tmp/a\' b/2.txt
cat: /tmp/a\: No such file or directory
cat: b/1.txt: No such file or directory
cat: /tmp/a\: No such file or directory
cat: b/2.txt: No such file or directory

Ответы [ 3 ]

12 голосов
/ 21 января 2011

См. http://mywiki.wooledge.org/BashFAQ/050

TLDR

Поместите ваши аргументы в массив и назовите вашу программу как myutil "${arr[@]}"

#!/bin/bash -xv

file1="file with spaces 1"
file2="file with spaces 2"
echo "foo" > "$file1"
echo "bar" > "$file2"
arr=("$file1" "$file2")
cat "${arr[@]}"

выход

file1="file with spaces 1"
+ file1='file with spaces 1'
file2="file with spaces 2"
+ file2='file with spaces 2'
echo "foo" > "$file1"
+ echo foo
echo "bar" > "$file2"
+ echo bar
arr=("$file1" "$file2")
+ arr=("$file1" "$file2")
cat "${arr[@]}"
+ cat 'file with spaces 1' 'file with spaces 2'
foo
bar
6 голосов
/ 21 января 2011

Это может быть хорошим вариантом использования для общей команды "set" , которая устанавливает параметры оболочки верхнего уровня в список слов. То есть $ 1, $ 2, ... а также $ * и $ @ получают сброс.

Это дает вам некоторые преимущества массивов, в то же время оставаясь полностью совместимым с Posix-shell.

Итак:

set "arg with spaces" "another thing with spaces"
cat "$@"
5 голосов
/ 21 января 2011

Самая простая версия вашего примера сценария оболочки , которая будет работать правильно:

#! /bin/sh

ARG="/tmp/a b/1.txt"
ARG2="/tmp/a b/2.txt"

cat "$ARG" "$ARG2"

Однако, если вам нужно обернуть целую кучу аргументов в одну переменную оболочки, значит, вы в самом разгаре; нет портативного, надежного способа сделать это. (Массивы являются специфичными для Bash; единственные переносимые опции - set и eval, оба из которых требуют скорби.) Я бы посчитал необходимость в этом показателем того, что пришло время переписывать более мощный сценарий язык, например Perl или Python.

...