Miałem dziwne zachowanie dziś rano w terminalu bash:
user@home:/home/user$ [ -f /etc/openvpn/client.conf ] && echo true
bash: [: missing «]»
user@home:/home/user$ [ -f /etc/openvpn/client.conf ] && echo true
true
- Pierwsze polecenie zostało wklejone ze skryptu edytowanego za pomocą gedit.
- Drugi wpisano bezpośrednio w terminalu.
Po pewnym kopaniu dowiaduję się, że usunięcie 30-tego znaku (spacja między klientem.conf a „]”) i zastąpienie go spacją sprawiło, że polecenie znów działało.
Moje założenie było słuszne: nieznana pusta postać wpadła do komendy , ale pytanie brzmi:
- Jak mogę ujawnić te znaki w terminalu, aby móc debugować polecenie? I co ważniejsze:
- Jak mogę temu zapobiec?
BTW, mam system Ubuntu 18.04 / francuski, skrypt, z którego wklejam polecenie, znajduje się na dysku USB i mógł być edytowany także w systemie Windows.
Dziękuję za bardzo dobre odpowiedzi. Zły znak to znak UTF-8, który nie łamie c2 a0 . Pytanie, jak usunąć specjalną postać „M-BM-” za pomocą sed, ma interesujący fakt na temat tej postaci.
Dziwne jest to, że skrypt nie zawiera tej postaci. Więc nie wiem skąd się wziął.
linux
bash
gnome-terminal
Gabriel Glenn
źródło
źródło
history 2|xxd
(ponieważhistory
samo polecenie jest zawsze ostatnie na liście), lub wpiszhistory|grep "CommandWithProblem"|xxd
. Zamiast tego możesz użyć dowolnego innego programu do wyświetlania szesnastkowegoxxd
, ale domyślnie jest to format, który mi się podoba.set -x
. To pokaże ci polecenie i jak jest podzielone. To niekoniecznie oznaczałoby „zły charakter tutaj”, ale pokazywałoby, że bash nie dzielił się z tą postacią.Odpowiedzi:
Jedną z opcji jest spojrzenie na znaki, których próbujesz użyć w przeglądarce szesnastkowej lub edytorze.
hexdump
jest dobrym rozwiązaniem, jeśli jesteś ograniczony do terminala.Widać tutaj, że
space
,close-square-brace
,space
są prawidłowe -0x20
,0x5D
,0x20
.Te wartości są kodami ASCII wyświetlanymi w systemie szesnastkowym . Każda wartość spoza zakresu
0x20
-0x7E
nie jest „ drukowalnym znakiem ” w odniesieniu do ASCII i najprawdopodobniej nie będzie dobrze grała z interfejsami linii poleceń.Uwaga: Skopiowałem pierwszą „ przerwaną ” linię do użycia w
hexdump
powyższym przykładzie, więc coś zastąpiło spację inną niż ASCII spacją ASCII między oryginalnym źródłem a renderowanym pytaniem.Aby powtórzyć, wykonaj następujące czynności:
hexdump -Cv <<"EOF"
i naciśnijEnterEOF
własną linię i naciśnijEnterTerminale i interfejsy wiersza poleceń nie radzą sobie dobrze ze znakami specjalnymi - jak odkryłeś. Jeśli nie jesteś bardzo ostrożny z formatowaniem dokumentów, będziesz mieć również problemy z Microsoft Word (i innymi) za pomocą „ inteligentnych cytatów ”, myślników, lista jest długa ...
Dostrzeż różnicę: (góra to „ inteligentne cytaty ”, dół to „ proste cytaty ”)
Tutaj otwarte cytaty nie są prostą ASCII cytat (
"
), lecz są Unicode / UTF-8 series -0xE2
,0x80
,0x9C
lubU+201C
- co terminal nie będzie obsługiwać jak można się było spodziewać.Sugestia Kiwy'ego
cat -A
również działa:Uwaga: podczas używania
echo "..." | hd
masz szansę, że bash zastąpi części ciągu, które próbujesz sprawdzić. Jest to szczególnie niepokojące przy próbie sprawdzenia składników skryptu.Na przykład spróbuj:
Te metody zastępują komponenty odpowiednim tekstem. Aby tego uniknąć, zastosuj jedno z następujących podejść. Zwróć uwagę na użycie pojedynczego cudzysłowu (
'
) i „ cytowanego heredoc ” ("EOF"
).źródło
echo "[ -f /etc/openvpn.ovpn ]" | hd
zwraca[...] c2 a0 [...]
. Widzimy nieprzerwaną przestrzeń c2 a0 UT-8Możesz użyć
cat
z-A
opcją: z instrukcji:Więc
cat -A yourscrip.sh
pokaże ci niewidzialne i dziwne postacie.źródło
echo "[ -f /etc/openvpn.ovpn ]" | cat -A
zwraca[ -f /etc/openvpn/client.ovpnM-BM- ]$
. Widzimy nieprzerwaną przestrzeń postaci M-BM- UT-8echo "<your command>" | hd
powinno działać. Poszukaj backspace (0x08) lub znaków z kodami> = 80.echo "<your command>" | wc -b
dobrym pomysłem jest również sprawdzenie, czy liczba zgadza się z tym, co widzisz.Kopiowanie plików z plików utworzonych przez cokolwiek z „Office” w nazwie jest niebezpieczne, ponieważ takie oprogramowanie często pozwala na zamianę znaków: po francusku wypatruj podwójnych cudzysłowów zastąpionych przez „gilemety”, po angielsku zwykłych cytatów zastępowanych przez ich otwieranie / zamykanie odpowiedników. Najtrudniejsze, jakie kiedykolwiek znalazłem, to niezniszczalna przestrzeń o szerokości 0 w środku nazwy pliku (3 dni przestoju serwera ...).
źródło
hd
skróthexdump
ten jest również wspomniany w odpowiedzi Attie.hd
jest równoważne zhexdump -C
.echo "[ -f /etc/openvpn.ovpn ]" | hd
zwraca[...] c2 a0 [...]
. Widzimy nieprzerwaną przestrzeń postaci C2 a0 UT-8Bash i inne powłoki, takie jak zsh, mogą otwierać bieżący wiersz poleceń w edytorze. Domyślny skrót dla bash jest
C-x C-e
( CtrlX CtrlE), a to otwiera się w pierwszy dostępny z$VISUAL
,$EDITOR
i emacs. W praktyce jest to nieocenione przy debugowaniu i modyfikowaniu złożonych poleceń. W zależności od tego, jak na to patrzysz, zsh jest tutaj bardziej przyjazny niż bash: kiedy edytor kończy działanie, bash natychmiast uruchamia polecenie, podczas gdy zsh czeka na naciśnięcie Enter(co daje większą szansę na edycję polecenia).Po otwarciu polecenia w edytorze możesz skonfigurować edytory, aby wyświetlały znaki inne niż ASCII w różny sposób.
Na przykład za pomocą Vima , używając tych ustawień:
Lub, dostosowując metody innych odpowiedzi:
źródło