Вы облажались. Вам сказали, что вы не можете отформатировать диск, потому что он уже использовался. Он был в употреблении. Вы пытались отформатировать один из существующих дисков, а не новый. Теперь вы отформатировали существующий диск и потеряли данные. Вам нужно будет восстановить из резервной копии.
Из вывода pvdisplay видно, что / dev / sdd1 на 100% свободен, так что, похоже, это новый диск.
I wrote a script which can generate those arguments for me, with quotes
Если выходные данные указаны для оболочки правильно, и вы доверяете выходным данным , то вы можете запустить на них eval
.
Предполагая, что у вас есть оболочка, поддерживающая массивы, было бы лучше использовать ее для хранения полученных аргументов.
Если ./gen_args.sh
выдает результат, аналогичный 'foo bar' '*' asdf
, то мы можем запустить eval "args=( $(./gen_args.sh) )"
для заполнения массива с именем args
результатами. Это будут три элемента foo bar
, *
, asdf
.
Как обычно, мы можем использовать "${args[@]}"
для расширения элементов массива по отдельности:
$ eval "args=( $(./gen_args.sh) )"
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
(Обратите внимание на кавычки. "${array[@]}"
расширяется на все элементы как отдельные аргументы без изменений. Без кавычек элементы массива подлежат разбиению на слова. См., например. страница Arrays в BashGuide .)
Однако , eval
будут успешно запускать любые подстановки оболочки, поэтому $HOME
в выводе будет расширяться до вашего домашнего каталога, а подстановка команд фактически запустит команду в оболочке, работающей eval
. Вывод "$(date >&2)"
создаст один пустой элемент массива и выведет текущую дату на стандартный вывод. Это вызывает беспокойство, если gen_args.sh
получает данные из какого-либо ненадежного источника, например, другого хоста в сети, имена файлов, созданные другими пользователями. Вывод может включать произвольные команды.(Если бы сам get_args.sh
был вредоносным, ему не нужно было бы ничего выводить, он мог бы просто запускать вредоносные команды напрямую.)
Альтернативой заключению в кавычки оболочки, которое трудно разобрать без eval, может быть использование какого-либо другого символа в качестве разделителя в выводе вашего скрипта. Вам нужно будет выбрать тот, который не нужен в реальных аргументах.
Давайте выберем #
и получим вывод сценария foo bar#*#asdf
. Теперь мы можем использовать расширение команды без кавычек , чтобы разделить вывод команды на аргументы.
$ IFS='#' # split on '#' signs
$ set -f # disable globbing
$ args=( $(./gen_args3.sh ) ) # assign the values to the array
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
Вам нужно будет снова установить IFS
позже, если вы зависите от разделения слов в другом месте скрипта(unset IFS
должно работать, чтобы сделать его значением по умолчанию ), а также использовать set +f
, если вы хотите использовать подстановку позже.
Если вы не используете Bash или другую оболочку с массивами, вы можете использовать для этого позиционные параметры. Замените args=( $(...) )
на set -- $(./gen_args.sh)
и используйте "$@"
вместо "${args[@]}"
. (Здесь тоже нужны кавычки вокруг "$@"
, иначе позиционные параметры подлежат разбиению на слова.)
Проблема в том, что после того, как ваш somecommand
скрипт выводит параметры для othercommand
, эти параметры на самом деле являются просто текстом и зависят от стандартного синтаксического анализа оболочки (, на который влияет то, что $IFS
происходит и что действуют параметры оболочки, которыми вы в общем случае не управляете ).
Вместо использования с somecommand
по для вывода опций было бы проще, безопаснее и надежнее использовать его для вызоваothercommand
. Скрипт somecommand
тогда будет скриптом-оболочкой вокруг othercommand
вместо какого-то вспомогательного скрипта, который вам нужно будет не забыть вызывать каким-то особым образом как часть командной строки otherscript
. Сценарии-оболочки — очень распространенный способ предоставления инструмента, который просто вызывает другой подобный инструмент с другим набором параметров (, просто проверьте с помощью file
, какие команды в /usr/bin
на самом деле являются оболочками сценариев оболочки ).
В bash
, ksh
или zsh
вы можете легко создать сценарий-оболочку, который использует массив для хранения отдельных параметров для othercommand
, например:
options=( "hi there" "nice weather" "here's a star" "*" )
options+=( "bonus bumblebee!" ) # add additional option
Затем вызовитеothercommand
(внутри скрипта-оболочки):
othercommand "${options[@]}"
Расширение "${options[@]}"
гарантирует, что каждый элемент массива options
будет отдельно заключен в кавычки и представлен в othercommand
как отдельные аргументы.
Пользователь оболочки не заметит тот факт, что она на самом деле вызывает othercommand
, что было бы не истинным, если бы сценарий вместо этого просто генерировал параметры командной строки для othercommand
в качестве вывода..
В /bin/sh
используйте $@
для сохранения опций:
set -- "hi there" "nice weather" "here's a star" "*"
set -- "$@" "bonus bumblebee!" # add additional option
othercommand "$@"
(set
— это команда, используемая для установки позиционных параметров $1
, $2
, $3
и т. д. Это то, что составляет массив $@
в стандартной оболочке POSIX. Начальный --
должен сигнализировать set
, что не задано никаких опций, только аргументы. --
на самом деле требуется только в том случае, если первое значение начинается с-
).
Обратите внимание, что двойные кавычки вокруг $@
и ${options[@]}
гарантируют, что элементы не будут разделены на отдельные слова -(и имена файлов ).
Если вывод somecommand
имеет надежный синтаксис оболочки, вы можете использоватьeval
:
$ eval sh test.sh $(echo '"hello " "hi and bye"')
hello
hi and bye
Но вы должны быть уверены, что выходные данные имеют допустимые кавычки и тому подобное, иначе вы можете в конечном итоге запустить команды вне скрипта:
$ cat test.sh
for var in "$@"
do
echo "|$var|"
done
$ ls
bar baz test.sh
$ eval sh test.sh $(echo '"hello " "hi and bye"; echo rm *')
|hello |
|hi and bye|
rm bar baz test.sh
Обратите внимание, что echo rm bar baz test.sh
не было передано сценарию (из-за;
)и выполнялось как отдельная команда. Я добавил |
вокруг $var
, чтобы выделить это.
Как правило, если вы не можете полностью доверять выходным данным somecommand
, невозможно надежно использовать их выходные данные для построения командной строки.