GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bewahren Sie Anführungszeichen in Bash-Argumenten auf

Die Anführungszeichen werden entfernt, bevor die Argumente an Ihr Skript übergeben werden, daher ist es zu spät, sie beizubehalten. Sie können ihre Wirkung beibehalten, wenn Sie die Argumente an den inneren Befehl übergeben, und eine äquivalente Version der Argumente mit Anführungszeichen/Escapezeichen zum Drucken rekonstruieren.

Zur Übergabe der Argumente an den inneren Befehl "[email protected]" -- mit den doppelten Anführungszeichen behält [email protected] die ursprünglichen Wortumbrüche bei, was bedeutet, dass der innere Befehl genau dieselbe Argumentliste erhält wie Ihr Skript.

Zum Drucken können Sie das %q-Format im printf-Befehl der Bash verwenden, um die Anführungszeichen zu rekonstruieren. Beachten Sie, dass dies nicht immer das ursprüngliche Zitat rekonstruiert, sondern ein Äquivalent erstellt Zeichenfolge in Anführungszeichen/mit Escapezeichen. Zum Beispiel, wenn Sie das Argument 'uptime ; uname -a' übergeben haben es könnte uptime\ \;\ uname\ -a ausgeben oder "uptime ; uname -a" oder ein anderes Äquivalent (siehe Antwort von @William Pursell für ähnliche Beispiele).

Hier ist ein Beispiel für die Verwendung dieser:

printf "Running command:"
printf " %q" innercmd "[email protected]" # note the space before %q -- this inserts spaces between arguments
printf "\n"
innercmd "[email protected]"

Wenn der Benutzer Ihren Befehl aufruft als:

./script 'foo'

Das erste Argument, das dem Skript übergeben wird, ist die Zeichenfolge foo ohne die Anführungszeichen. Es gibt keine Möglichkeit für Ihr Skript, zwischen dieser und einer der anderen Methoden zu unterscheiden, mit denen es foo erhalten könnte als Argument (zB ./script $(echo foo) oder ./script foo oder ./script "foo" oder ./script \f\o""''""o ).


Wenn Sie die Argumentliste so nah wie möglich an dem drucken möchten, was der Benutzer wahrscheinlich eingegeben hat:

#!/bin/bash
chars='[ !"#$&()*,;<>?\^`{|}]'
for arg
do
    if [[ $arg == *\'* ]]
    then
        arg=\""$arg"\"
    elif [[ $arg == *$chars* ]]
    then
        arg="'$arg'"
    fi
    allargs+=("$arg")    # ${allargs[@]} is to be used only for printing
done
printf '%s\n' "${allargs[*]}"

Es ist nicht perfekt. Ein Argument wie ''\''"' schwieriger unterzubringen ist als gerechtfertigt.


Linux
  1. Der „eval“-Befehl in Bash?

  2. Befehlszeilenargumente an Bash-Skript übergeben?

  3. Wie kann ich das Argument des vorherigen Bash-Befehls abrufen?

  4. Bash-Exportbefehl

  5. bash-Alias-Befehl mit einfachen und doppelten Anführungszeichen

Bash-Quellbefehl

Verlaufsbefehl in Linux (Bash-Verlauf)

Bash Exit-Befehl und Exit-Codes

Bash-printf-Befehl

Bash-Skripting (II)

Bash-Scripting(III)