Zastanawiam się, dlaczego to nie działa
#!/bin/bash
ls /bin
ls !$
Spodziewam się uruchomić ls /bin
dwa razy, ale drugi powoduje błędy, których !$
nie interpretowano
Coś przeoczyłem lub !$
pracowałem tylko w linii poleceń?
Nie mogłem znaleźć odpowiedniej części w man bash
(na Macu)
Odpowiedzi:
Historia i ekspansja historii są domyślnie wyłączone, gdy powłoka działa nieinteraktywnie.
Potrzebujesz:
lub:
wpłynie to na wszystkie
script.sh
uruchamiane instancje bash .źródło
bash
że działascript.sh
, ale także na wszystkie innebash
instancje, którescript.sh
mogą ostatecznie zostać uruchomione (podobnie jak innebash
skrypty ...).bash
instancję, która uruchamia twój skrypt.Byłoby rozsądne
lub
lub
Ostrzeżenia: warto pamiętać, że każdy z nich wiąże się z pewnymi pułapkami. Rozwiązanie $ _ przechwytuje tylko ostatni pojedynczy argument: więc
ls foo bar
pozostawi $ _ zawierający justbar
. Jedna z użyciemset
zastępują argumenty ($1
,$2
itp). Wszystko to, jak napisano, zadziała, ale po uogólnieniu na bardziej złożone polecenia (gdzie znaczenie ma znak ucieczki i spacja), możesz napotkać pewne trudności. Na przykład:ls 'foo bar'
(gdy argument pojedynczej ścieżkifoo bar
zawiera dwie lub więcej spacji lub dowolne inne znaki spacji) nie będzie działał poprawnie w żadnym z tych przykładów. W celu obejścia tych przypadków może być konieczne prawidłowe ucieczkę (ewentualnie w połączeniu zeval
poleceniem) lub użycie"$@"
zamiast$*
.źródło
$_
Sposób nie jest przenośny, masz rację.set
Podejście działa w nieinterakcyjnym kreską iz${1+"$@"}
(Plus zsh globalny alias) sztuczki powinny być ogólne, choć niejasno pamiętać, żeset
ma historię nie będąc doskonale przenośny z niektórych (?) Starych powłok. Podejście „definiuj zmienne trzymanie polecenia-a-następnie-ewaluuj-to”, zwłaszcza przy użyciu właściwego ucieczki i rzeczywistegoeval
polecenia, jest całkowicie przenośne, o ile mi wiadomo.