Bash: Testen Sie, ob das ursprüngliche Skript mit `-x` ausgeführt wurde

7

Ist es möglich zu testen, ob ein Bash-Skript mit ausgeführt wurde -x?

Ich schreibe ein Skript, in dem auch einige Remote-Skripte ausgeführt werden, und ich möchte in der Lage sein, Folgendes zu tun:

USE_X="$( run_with_x && "-x" || "" )"
ssh $host "bash $USE_X some_script.sh"
David Wolever
quelle

Antworten:

9

Schauen Sie sich einfach die $-Variable an.

USE_X=`case "$-" in *x*) echo "-x" ;; esac`

(Ja, ich habe es geschafft, ohne grep aufzurufen. Speichern Sie die Pids!)

dagbrown
quelle
Worauf *x*erweitert sich?
bbaja42
2
Was für eine Verschwendung von PID! case $- in *x*) USE_X="-x";; *) USE_X=;; esac@ bbaja42 Es wird nicht erweitert: Es ist ein Muster, mit dem die Zeichenfolge $-abgeglichen wird.
Gilles 'SO - hör auf böse zu sein'
@ Gilles Ihr Beispiel enthält auch unnötige Teile: *) USE_X=;;ändert nichts, wenn USE_Xes nicht zuvor festgelegt wurde. Auch das ganze caseKonstrukt ist unnötig ( siehe meine Version - ist das nicht einfacher?)
rozcietrzewiacz
@rozcietrzewiacz Dieser Teil ist nicht erforderlich, wenn er USE_Xzuvor initialisiert wurde. Ich halte Ihre Version nicht für einfacher: Sie ist einige Zeichen kürzer (und selbst dann nur, wenn USE_Xsie initialisiert wurde, andernfalls ist sie länger), aber auf Kosten der Klarheit und Portabilität.
Gilles 'SO - hör auf böse zu sein'
@ Gilles Portability ist nicht das Thema dieser Frage, es geht um Bash. Die Initialisierung USE_X ist für die beabsichtigte Verwendung von OP nicht erforderlich (um $USE_Xan weitere Skripte weitergegeben zu werden). Die Verwendung eines caseKonstrukts sieht meiner Ansicht nach weniger klar und natürlich aus als eine reguläre Zustandsbewertung.
Rozcietrzewiacz
6

Wahrscheinlich die einfachste Art des Parsens $-, ähnlich der Methode von dagbrown (ebenfalls rein bash), jedoch ohne Verwendung caseund Backticks (Subshell):

if  [[ ${-/x} != $- ]] ; then USE_X="-x"; fi

oder noch kürzer:

[[ ${-/x} != $- ]] && USE_X="-x"

Beachten Sie, dass [[ist nicht ein Aufruf von testeingebautem Programm (wie es der Fall mit [), aber ein bash Syntax - Konstrukt (nach man bashund dieser Entwickler Empfehlung ). Also behaupte ich, es sei "purer bash";)

rozcietrzewiacz
quelle
Schöne Lösung. Ich schlage vor, '|| zu markieren USE_X = "+ x" 'am Ende des zweiten Ausdrucks, sodass Sie dann' set "$ USE_X" 'aufrufen können, um die ursprüngliche Einstellung wiederherzustellen, unabhängig davon, ob xtrace festgelegt wurde oder nicht.
Binary Phile
6

Dieser Ausdruck ist wahr, wenn das Skript ausgeführt wird -x, andernfalls falsch: [[ $- =~ x ]] Dieser Ausdruck ist also "-x", wenn das Skript ausgeführt wird, -xund "" (leer), andernfalls:$([[ $- =~ x ]] && echo "-x")

PePa
quelle
Es ist eine Strecke, im selben Satz "lesbar" und "Bash" zu sagen, aber da jeder nicht-zufällige Bash-Benutzer sich mit der Bash-Regex-Syntax vertraut machen muss, gewinnt Ihre (derzeit am niedrigsten bewertete) Antwort für die Lesbarkeit in meinem Buch (und Natürlich müssen keine Prozesse gestartet werden oder etwas erstaunlich Ineffizientes.
Ron Burk
Das ist die beste Antwort!
Chris Cogdon
Dieser Ausdruck entfernt alle Nicht-x-Zeichen aus $ -, ist also leer, wenn kein x vorhanden ist: ${-//[^x]}Wenn Sie dies einer Variablen zuweisen, wie z. B.: x=${-//[^x]}Der folgende Ausdruck ist leer, wenn kein x und -x vorhanden sind. Andernfalls: ${x:+-x} Kombinieren Sie wie : x=${-//[^x]} USE_X=${x:+-x} Oder wenn Sie keine zusätzliche Variable verwenden möchten, können Sie USE_X wiederverwenden: USE_X=${-//[^x]} USE_X=${USE_X:+-x} Dies ist viel schneller als ein Vergleich mit regulären Ausdrücken! (Aber weniger lesbar, wenn man nur den Code betrachtet und herausfindet, was er tut ...)
PePa
4

Nachdem Sie Manpages gelesen und nach Dingen gesucht haben, finden Sie hier die Lösung:

$ cat show_x.sh
#!/bin/bash
if [ "$(set | grep xtrace)" ]; then
    echo "xtrace is on. :D"
else
    echo "xtrace is off. :("
fi

Ergebnis:

$ bash show_x.sh 
xtrace is off. :(

$ bash -x show_x.sh 
++ set
++ grep xtrace
+ '[' SHELLOPTS=braceexpand:hashall:interactive-comments:xtrace ']'
+ echo 'xtrace is on. :D'
xtrace is on. :D
shazow
quelle
"set" zeigt Ihnen alle Funktionen und Umgebungsvariablen an, und wenn eine dieser Funktionen "xtrace" enthält, schlägt die Lösung fehl.
Chris Cogdon
3

Die Bash-Manpage dokumentiert set -o xtraceals äquivalent zu set -x, was wiederum gleichbedeutend ist mit der Angabe -xals Argument für die Shell. (Bisher ist dies mit SUSv3 sh kompatibel, mit der Einschränkung, dass -o option"wenn das System die Option User Portability Utilities unterstützt" erforderlich ist.)

Auch set -oohne eine Option druckt den aktuellen Status aller von den -oOptionen. (SUSv3 gibt dies ebenfalls an, jedoch nicht sinnvoll. Das Format ist nicht angegeben. Sie können sich also nur darauf verlassen, wenn Sie wissen, dass Sie eine Shell ausführen, die ein ähnliches Format wie Bash verwendet.)

Die Pipeline set -o | grep xtrace | grep -q onsollte also genau das sein, wonach Sie suchen.

Dave Vandervies
quelle