2015-11-19 1 views
2

Предположит, у меня есть файл, содержащий params.txt содержаниямногословных аргументов из кавычки (команда подстановки)

--option "option 1" --option "option 2" 

Я хотел бы иметь возможность использовать содержимое params.txt в качестве аргументов командной строки для некоторой программы, myProg:

./myProg $(cat params.txt) 

или

./myProg `cat params.txt` 

Но это не работает: он рассматривает аргументы с несколькими словами как несколько аргументов, а не одинарные кавычки. Есть ли способ использовать команду подстановки (или какой-либо другой Баш особенность, которую я не знаю о), чтобы вытащить аргументы из params.txt и получить

./myProg --option "option 1" --option "option 2" 

как исполняемой команды?

+0

Является ли 'params.txt' написанным человеком или частью программного обеспечения? –

+0

... если это исходит из программного обеспечения, лучший выбор - сделать его NUL-ограниченным, а не shell-quoted. –

+0

Спасибо. Это написано человеком. Если бы это было NUL-делимитировано, можно ли легко использовать его в bash? EDIT: просто увидели обновление вашего ответа. Спасибо! –

ответ

3

Если params.txt написана человеком, которому вы доверяете, вы можете сделать это с eval:

eval "./myProg $(<params.txt)" 

Чтобы безопасно написать eval -safe поток из сценария будет выглядеть вместо так:

printf '%q ' --option "option 1" --option "option 2" >params.txt 

Лучший способ сохранять параметры однозначно и использовать их без the serious security risks caused by eval, является потоком, ограниченным NUL:

# write params file 
printf '%s\0' --option "option 1" --option "option 2" >params 

... а затем, чтобы потреблять, что ...

# read params file into array 
params=() 
while IFS= read -r -d '' param; do 
    params+=("$param") 
done <params 

# use that array to call your program 
./myProg "${params[@]}" 

Обратите внимание, что эта последняя форма не совместима с подстановкой команд, но может использоваться с заменой процесса, если вы «Чтение вывода из команды более интересно, чем cat (что лучше всего заменить простым переадресацией). Таким образом:

# this does not work: depends on NULs being stored in a shell variable 
while IFS= read -r -d '' param; do params+=("$param"); done <<<"$(...command here...)" 

# this works 
while IFS= read -r -d '' param; do params+=("$param"); done < <(...command here...) 

Обратите внимание, что замещение процесса - это функциональность, отсутствующая в POSIX sh; убедитесь, что ваш shebang указывает оболочку (например, #!/bin/bash) с этой поддержкой.

Смежные вопросы