2010-09-20 9 views
9

Powiedzmy mam naprawdę prosty skrypt powłoki 'foo':

#!/bin/sh 
    echo [email protected] 

Gdybym powołać go tak:

foo 1 2 3 

To szczęśliwie drukuje:

1 2 3 

Jednak niech jeden z moich argumentów zawiera podwójne cytowanie i zawiera białe spacje:

foo 1 "this arg has whitespace" 3 

foo szczęśliwie drukuje:

1 this arg has whitespace 3 

podwójnie cytaty zostały usunięte! Wiem, że shell myśli, że robi mi przysługę, ale ... chciałbym dostać oryginalną wersję argumentów, niezmienioną przez interpretację powłoki. Czy jest jakiś sposób to zrobić?

Odpowiedz

1

trzeba przytoczyć cytaty:

foo 1 "\"this arg has whitespace\"" 3 

lub (prościej)

foo 1 '"this arg has whitespace"' 3 

trzeba zacytować cudzysłów, aby upewnić się, że powłoka nie je usunąć podczas analizowania argumenty słowne.

6

Najpierw prawdopodobnie chcesz zacytować wersję [email protected], tj. "[email protected]". Aby poczuć różnicę, spróbuj umieścić więcej niż jedną spację w ciągu.

Po drugie, cytaty są elementem składni powłoki - nie wyświadcza się przysługi. Aby je zachować, musisz im uciec. Przykłady:

foo 1 "\"this arg has whitespace\"" 3 

foo 1 '"this arg has whitespace"' 3 
2

Pokój cytat $ @:

#!/bin/sh 
for ARG in "[email protected]" 
do 
    echo $ARG 
done 

Następnie:

foo 1 "this arg has whitespace" 3 

daje:

1 
this arg has whitespace 
3 
+0

A następnie można użyć 'IFS', aby uniknąć cytowania piekła zademonstrowanego w innych odpowiedziach, jeśli chce się zrobić coś użytecznego z takimi parametrami ... –

2

Załóżmy, że jesteś w bardziej sztywny zestaw -up i NIE MOŻESZ zmienić linii poleceń i zrobić jest bardziej "przyjazny", uciekając przed podwójnymi cytatami. Na przykład:

example_script.sh argument_without_quotes "argument with quotes i cannot escape" 

pierwsze uważają, że wewnątrz skryptu nie można stwierdzić, czy argument jest przekazywany z lub bez cudzysłowów, ponieważ powłoka pozbawia je.

Więc co można ewentualnie zrobić to odbudowy cudzysłowów argumentów zawierających spacje

Przykład ten odbudowuje całą linię poleceń dwukrotnie przytoczyć argumenty, które mają białe przestrzenie

#!/bin/sh 
#initialize the variable that will contain the whole argument string 
argList="" 
#iterate on each argument 
for arg in "[email protected]" 
do 
    #if an argument contains a white space, enclose it in double quotes and append to the list 
    #otherwise simply append the argument to the list 
    if echo $arg | grep -q " "; then 
    argList="$argList \"$arg\"" 
    else 
    argList="$argList $arg" 
    fi 
done 

#remove a possible trailing space at the beginning of the list 
argList=$(echo $argList | sed 's/^ *//') 

#pass your argument list WITH QUOTES 
echo "my_executable" $argList 
#my_executable $argList 

Uwaga to ograniczenie . Jeśli uruchomić ten przykład

dostaniesz to wyjście

my_executable "argument with spaces" argument_without_spaces argument_doublequoted_but_without_spaces 

zanotować ostatni argument: skoro nie miała miejsca, nie został ponownie ujęty w cudzysłów, ale nie powinno to być problemem.

2

Pozwolę sobie zacytować wszystkie argumenty otrzymane ze spacjami, które mogą pomóc w twojej sprawie.

for x in "${@}" ; do 
    # try to figure out if quoting was required for the $x 
    if [[ "$x" != "${x%[[:space:]]*}" ]]; then 
     x="\""$x"\"" 
    fi 
    echo $x 
    _args=$_args" "$x 
done 

echo "All Cmd Args are: $_args" 
Powiązane problemy