Próbuję użyć polecenia curl, aby uzyskać dostęp do adresu URL z wykrzyknikiem ( !
) na ścieżce. na przykład:
curl -v "http://example.org/!287s87asdjh2/somepath/someresource"
konsola z odpowiedzi bash: ... event not found
.
Co tu się dzieje? i jaka byłaby właściwa składnia, aby uniknąć wykrzyknika?
bash
quoting
special-characters
sieć mózgu
źródło
źródło
Odpowiedzi:
Wykrzyknik jest częścią ekspansji historii w bash. Aby go użyć, musisz go ująć w pojedyncze cudzysłowy (np .:)
'http://example.org/!132'
lub bezpośrednio uciec ukośnikiem odwrotnym (\
) przed znakiem (np"http://example.org/\!132"
.:).Zauważ, że w podwójnych cudzysłowach odwrotny ukośnik przed wykrzyknikiem zapobiega rozszerzeniu historii, ALE odwrotny ukośnik nie jest usuwany w takim przypadku. Lepiej więc używać pojedynczych cudzysłowów, aby nie podawać dosłownego odwrotnego ukośnika
curl
jako części adresu URL.źródło
"http://example.org/\!132"
faktycznie rozwija się bez interpretacji ukośnika odwrotnego (uważam, że jest to zgodne z POSIX).\!
i podwójnie cytował.|
i służy do tworzenia potoku. Jeśli wysyłasz skrypty do klientów i nie masz pewności, w jakiej powłoce będą one uruchamiane, musisz przetestować je wszystkie!Oprócz odpowiedzi udzielonej przez Daniela możesz także po prostu całkowicie wyłączyć rozszerzanie historii, jeśli jej nie używasz
set +H
.źródło
Ctrl-R
), które umożliwiają podgląd i edycję polecenia, abyś nie ślepo strzelał z poleceniem,!-14
które ci się!-12
wydawało, upsrm -rf *
. Bądź bezpieczny. Wyłącz rozszerzanie historii! Unikaj!
!fc -14
przez POSIX . Ale to prawda, że możesz to zrobić bez włączonego rozszerzenia historii. Osobiście używam!$
i!vi
asudo !!
, a nawetgit add !vi:$
dość często, aby uzasadnić pozostawiając włączony ekspansja historia.Osobiście robiłbym pojedyncze cytaty, ale dla kompletności, również zauważę, ponieważ jest to adres URL, możesz zakodować
!
jako%21
npcurl -v http://example.org/%21132
.źródło
To też może zrobić
curl -v "http://example.org/"'!'"287s87asdjh2/somepath/someresource"
lub
curl -v "http://example.org/"\!"287s87asdjh2/somepath/someresource"
Co działa, ponieważ bash łączy sąsiednie łańcuchy. To podejście jest szczególnie przydatne, gdy masz inne rzeczy, które wymagają rozszerzenia powłoki, więc nie możesz używać pojedynczych cudzysłowów dla całego łańcucha:
curl -v 'http://example.org/!'"287s87asdjh2/${basepath}/someresource"
!
znak służy do rozszerzania historii w wierszu polecenia.może to być problemem w pytaniu, ale nie w plikach skryptów powłoki.
jak widać rozszerzenia historii działają nawet w podwójnych cudzysłowach.
źródło
Natknąłem się na ten sam problem, a moim prostym rozwiązaniem było użycie zmiennej:
Tutaj prostota polega na tym, że (1) jest przenośny między powłokami i poleceniami (2) Nie wymaga znajomości składni Escape i kodów ASCII.
źródło
Od czasu wersji Bash 4.3 możesz teraz używać podwójnych cudzysłowów, aby zacytować znak rozszerzenia historii:
źródło
echo
, echo wydaje się radzić sobie z tym inaczejbash
wersja nie ma nic wspólnego z tym, że huk nie jest rozszerzany, wynika to z faktu, że w twoim przykładzie!
następuje „koniec linii”, co uniemożliwia powłoce próbę jej rozwinięcia. Spróbuj,echo "!Hello World"
a zobaczysz, żebash
odpowiebash: !Hello: event not found
. Więcej informacji na ten temat można znaleźć w instrukcji obsługiDla tych, którzy używają git bash w Windows, działa odpowiedź zaakceptowana przez @DanielPittman. Powinieneś jednak zastąpić ukośnik odwrotny (\) ukośnikiem (/).
Na przykład w Uniksie wyglądałby mniej więcej tak:
curl https://abc.com/services -H 'Authorization: Bearer 111A80BBZZCnS\!ZR412543s'
W przypadku systemu Windows byłoby to mniej więcej tak (skoncentruj się na ukośniku w części nagłówka autoryzacji)
curl https://abc.com/services -H 'Authorization: Bearer 111A80BBZZCnS/!ZR412543s'
źródło