Czy ktoś wie, czy możemy powiedzieć set +x
w bashu bez drukowania:
set -x
command
set +x
ślady
+ command
+ set +x
ale powinien po prostu wydrukować
+ command
Bash to wersja 4.1.10 (4). Od jakiegoś czasu mnie to niepokoi - wyjście jest zaśmiecone bezużytecznymi set +x
wierszami, przez co narzędzie śledzenia nie jest tak przydatne, jak mogłoby być.
script.sh 2>&1 | grep -v 'set +x'
Odpowiedzi:
Miałem ten sam problem i udało mi się znaleźć rozwiązanie, które nie używa podpowłoki:
set -x command { set +x; } 2>/dev/null
źródło
set +x
to takie udane poleceniecommand
, ta odmiana jest rozwiązanie:{ STATUS=$?; set +x; } 2>/dev/null
. Następnie$STATUS
w wolnym czasie sprawdź kolejne linie.{ set +x; } 2>&-
. To całkowicie zamyka fd 2, zamiast wskazywać na / dev / null. Niektóre programy nie radzą sobie tak dobrze, gdy próbują drukować na stderr, dlatego / dev / null jest ogólnie dobrym stylem; aleset -x
śledzenie muszli radzi sobie z tym dobrze, więc działa tutaj idealnie i sprawia, że inkantacja jest nieco krótsza.Możesz użyć podpowłoki. Po wyjściu z podpowłoki ustawienie
x
zostanie utracone:( set -x ; command )
źródło
( set -x \n command \n )
nic gorszego niżset -x \n command \n set +x
.cd
: nie zmienia bieżącego katalogu w powłoce nadrzędnej.Niedawno zhakowałem rozwiązanie tego problemu, kiedy to mnie zdenerwowało:
shopt -s expand_aliases _xtrace() { case $1 in on) set -x ;; off) set +x ;; esac } alias xtrace='{ _xtrace $(cat); } 2>/dev/null <<<'
Pozwala to włączać i wyłączać xtrace, jak poniżej, gdzie loguję, jak argumenty są przypisywane do zmiennych:
xtrace on ARG1=$1 ARG2=$2 xtrace off
Otrzymasz wynik, który wygląda następująco:
źródło
/dev/stdin
części). Zastrzeżenie polega na tym, że włączenie rozszerzania aliasów w skryptach może mieć niepożądane skutki uboczne./dev/stdin
. Nie znam żadnych konkretnych skutków ubocznych, ponieważ nieinteraktywne środowisko nie powinno ładować żadnych plików, które definiują aliasy. Jakie mogą wystąpić skutki uboczne?set +x
o wiele trudniej (jeśli nie niemożliwe) jest pójść na kompromis. Ale to wciąż dobre i proste rozwiązanie - chyba najlepsze do tej pory.Co powiesz na rozwiązanie oparte na uproszczonej wersji @ user108471:
shopt -s expand_aliases alias trace_on='set -x' alias trace_off='{ set +x; } 2>/dev/null' trace_on ...stuff... trace_off
źródło
function () { set_plus_x='{ set +x; } 2>/dev/null' }
Jest to kombinacja kilku pomysłów, które mogą obejmować blok kodu i zachować status wyjścia.
#!/bin/bash shopt -s expand_aliases alias trace_on='set -x' alias trace_off='{ PREV_STATUS=$? ; set +x; } 2>/dev/null; (exit $PREV_STATUS)' trace_on echo hello trace_off echo "status: $?" trace_on (exit 56) trace_off echo "status: $?"
Po wykonaniu:
$ ./test.sh + echo hello hello status: 0 + exit 56 status: 56
źródło
()
wokółexit
nie jest to konieczne. Ok. Może to jest paranoikiem, ale jeśli ten kod jest używany w ogóle masz dobry wektora ataku: zmiana definicjitrace_on
oraztrace_off
i wstrzyknąć kod, który wczytuje wykonywanych poleceń. Jeśli używasz tylko takich „narzędzi”, jest to pouczające, ale jeśli kod jest używany z innymi, musisz rozważyć, czy zalety takich niestandardowych funkcji przeważają nad wadami. Osobiście się z{ set +x; } 2>/dev/null
tym zdecydowałem, ponieważ ta konstrukcja jest powszechnie rozumiana i również nie zmienia statusu wyjścia.()
całegoexit 56
; tylko po to, abym mógł wykazać, że status wyjścia podprocesu był dostępny w skrypcie bash; bez parenów nie stałby się podprocesem, a skrypt zakończyłby pracę w tym momencie ze statusem = 65.