Как передать параметры командной строки из файла - PullRequest
3 голосов
/ 05 июля 2011

У меня есть программа на C, которая читает аргументы командной строки из argv.Можно ли создать канал для перенаправления содержимого файла в качестве аргументов командной строки в мою программу?Предположим, у меня есть файл arguments.dat с этим содержимым:

0 0.2 302 0

И я хочу, чтобы моя программа вызывалась с:

./myprogram 0 0.2 302 0

Я попробовал следующее:

cat arguments.dat | ./myprogram

без успеха.

Ответы [ 3 ]

11 голосов
/ 05 июля 2011

xargs ваш ответ:

cat arguments.dat | xargs ./myprogram

Или проще:

xargs -a arguments.dat ./myprogram

Проверьте в руководстве много способов настройки xargs.Например, вы можете читать построчно, а не словом, и можете использовать аргументы в более сложных заменах.

5 голосов
/ 05 июля 2011

В большинстве оболочек вы можете вставить содержимое файла в командную строку с помощью $(<filename):

./myprogram $(<arguments.dat)

Если ваша оболочка не поддерживает это, тогда будет работать один из старых способов.:

./myprogram $(cat arguments.dat)
./myprogram `cat arguments.dat`   # need this one with csh/tcsh

(Вы знаете разницу между аргументами командной строки и вводом файла, верно? Почему вы ожидаете передать аргументы командной строки в программу?)

2 голосов
/ 20 июня 2018

, если вы не хотите, чтобы аргументы были тихо разделены

... то есть: приведенные ниже ответы относятся к случаям, когда было бы неприемлемо, чтобы ./myprogram --first-argument "first value" было тихо изменено на./myprogram --first-argument; ./myprogram "first value".

Если ваши аргументы являются строковыми литералами

То есть, если ваш ввод выглядит так:

--first-argument
first value
--second-argument
second value

и вы имеете в виду этодля запуска:

./myprogram --first-argument "first value" --second-argument "second value"

... тогда вы должны использовать (с bash 4.0 или новее):

readarray -t args <arguments.dat
./myprogram "${args[@]}"

... или (также для bash 3.x):

args=( )
while IFS= read -r arg; do
  args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"

Если ваши аргументы снабжены кавычками или экранированными для их различения

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

--first-argument "first value"
--second-argument "second value"

... и вы хотите запустить:

./myprogram --first-argument "first value" --second-argument "second value"

... тогда вы должны использовать:

args=( )
while IFS= read -r -d '' arg; do
  args+=( "$arg" )
done < <(xargs printf '%s\0' <arguments.dat)

ЕслиВы управляете форматом аргумента

Используйте значения, разделенные NUL.То есть создайте файл следующим образом:

printf '%s\0' "argument one" "argument two" >arguments.dat

... и проанализируйте его следующим образом:

args=( )
while IFS= read -r -d '' arg; do
  args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"

Это будет работать с всеми возможными значениями аргументадаже с буквенными символами новой строки, буквенными кавычками, литеральными обратными слешами или другими непечатаемыми символами.(Буквенные NUL невозможны в командных строках UNIX, так как командные строки состоят из строк, оканчивающихся NUL; таким образом, NUL является единственным символом, который абсолютно безопасно использовать для однозначного разделения аргументов в строке).


Если желательно разделение аргументов между вызовами

Этот подраздел уместен, если желаемый результат (когда в вашем файле больше аргументов, чем может быть передано для вызова вашей программы)это несколько различных вызовов программы, каждый из которых получает подмножество аргументов.Это семейство случаев, когда xargs является подходящим инструментом для работы.

Если на платформе GNU, вы можете запустить xargs -a arguments.dat вместо перенаправления stdin;однако, это не поддерживается с BSD xargs (как в MacOS), и поэтому здесь не демонстрируется.

Если ваши аргументы являются литералами типа «один в строку»

С GNU xargs(большинство платформ Linux):

xargs -d $'\n' ./myprogram <arguments.dat

С BSD xargs (MacOS, FreeBSD / OpenBSD / и т. д.):

xargs -0 ./myprogram < <(tr '\n' '\0' <arguments.dat)

Если ваши аргументы снабжены кавычками или экранированием для их различения

xargs ./myprogram <arguments.dat

Если вы создали входы с разделителями NUL

xargs -0 ./myprogram <arguments.dat
...