2015-07-08 16 views
5

Mam plik zawierający argumenty wiersza poleceń, które chciałbym przekazać do innego skryptu. Ten plik zawiera element taki jak "param 1" param2 param3.Argument wiersza polecenia z treści pliku z cytatem

Nazwijmy plik z argumentami test.tmp i plikiem skryptowym script.sh.

Jeśli zrobić:

script.sh -p `cat test.tmp` -other_params 1 2 3 

script.sh otrzymuje po p:

  1. "param
  2. 1"
  3. param2
  4. param3

Ale chciałbym:

  1. param 1
  2. param2
  3. param3

Każdy pomysł?

Mała precyzja: załóżmy, że script.sh nie można modyfikować. Rozwiązanie musi się odbywać w powłoce.

+0

W idealnym świecie, 'test.tmp' powinny być przechowywane w NUL- rozdzielany formularz - składnia * only *, która może przechowywać wszystkie możliwe wartości bez potrzeby analizowania. (Bezpieczne przetwarzanie wycinków powłoki bez podejmowania ryzyka bezpieczeństwa, takiego jak zezwolenie na rozszerzenia, jest zaskakująco trudne - chyba że masz zamiar przekazać zadanie do czegoś takiego jak 'xargs', ale nawet wtedy jego zachowanie nie jest kompatybilne z rzeczywistym bashiem rozbiór gramatyczny zdania). Jeśli masz okazję zachęcić ludzi, którzy napisali 'script.sh' do ponownego rozważenia, sugerowałbym to. –

+0

Sugerowane przez Toma podejście "mapfile-t" jest również rozsądną praktyką, * jeśli * masz gwarancję, że twoje argumenty nigdy nie będą musiały zawierać literalnych znaków nowej linii. –

+0

BTW, zobacz http://mywiki.wooledge.org/BashFAQ/050 i jego linki (np. Na stronach WordSplitting i Arguments), aby dowiedzieć się więcej na temat * dlaczego * zachodzi domyślne zachowanie. –

Odpowiedz

6

Założenie:test.tmp musi zawierać parametr za Zgodnie z tym podejściem.

Można użyć xargs z ogranicznikiem nowego wiersza:

cat test.tmp | xargs -d '\n' script.sh -p 
+0

To działa idealnie. Mam kontrolę nad test.tmp, ale nie skrypt.sh. Dzięki –

+1

Jedno zastrzeżenie: jeśli masz naprawdę długą listę argumentów, 'xargs' uruchomi' script.sh' wiele razy z różnymi podzbiorami tej listy, zamiast natychmiast zawieść. W niektórych przypadkach może to być niepożądane. –

2

Rozłóż plik tak:

param 1 
param2 
param3 

następnie odczytać go do tablicy jak poniżej:

mapfile -t params < file 

następnie wywołać skrypt tak:

script.sh -p "${params[@]}" -other_params 1 2 3 

zaletę tego podejścia jest to, że używa tylko wbudowanych poleceń Bash i nie wymaga eval.

Aby zrobić to wszystko w jednej linii, można użyć:

mapfile -t params < file && script.sh -p "${params[@]}" -other_params 1 2 3 

tj używać && aby wykonać drugie polecenie, jeśli pierwszy udało.

1

Stosując grep z Perl regex:

IFS=$'\n'; ./script.sh -p $(grep -woP '((?<=")[^"]*(?="))|([\S]+)' test.tmp) 

Przykład:

scenariusza.sh:

#!/bin/bash 
echo "$1" 
echo "$2" 
echo "$3" 
echo "$4" 
... 

wyjściowa:

-p 
param 1 
param2 
param3 
... 

Uwaga: Spowoduje to zmianę IFS bieżącej powłoce (jeżeli używasz tych komend).

+0

To nie działa w przypadku mojego problemu. Przy wydatkowaniu wartości $ (...) pierwszym parametrem będzie "" parametr ", a drugim" 1 ". Kiedy potrzebuję pierwszego parametru, który będzie "param 1' –

+0

Podejście to wysyła (cytowane) wyjście grep jako drugi parametr do' skrypt.sh', podczas gdy OP oczekuje, że parametry "param2" i "param3" zostaną wysłane jako osobne argumenty. –

+0

@EugeniuRosca Edytowałem, myślę, że to zadziała .. – Jahid

6

można zawinąć polecenia w eval:

eval "script.sh -p `cat test.tmp` -other_params 1 2 3" 

$ cat test.tmp 
"params 1" param2 param3 

$ cat script.sh 
#!/bin/bash 
echo $1 
echo $2 
echo $3 
echo $4 
echo $5 
echo $6 

$ eval "./script.sh -p `cat test.tmp` other_params 1 2 3" 
-p 
params 1 
param2 
param3 
other_params 
1 
+2

Eww. Nie rób tego, chyba że zaufasz treści 'test.tmp'; jeśli zawiera, powiedzmy, '$ (rm -rf.)', czeka cię zły dzień. –

+0

Tak, to jest ogólnie dobra rzecz, ale OP powiedział, że ma kontrolę nad 'test.tmp' w tym przypadku, więc nie ma niebezpieczeństwa. –

+0

Jedną rzeczą jest kontrolować format pliku, a inną kontrolować jego zawartość. Jeśli jestem właścicielem skryptu, który pisze 'foo.txt', ale dane wyjściowe tego skryptu są zapisywane na podstawie danych wejściowych podanych w czasie wykonywania, to chyba bardzo uważam, że moje dane wyjściowe nadal nie mogą być uznane za nie złośliwe. –

Powiązane problemy