W danej powłoce normalnie ustawiłbym zmienną lub zmienne, a następnie uruchomiłem polecenie. Ostatnio dowiedziałem się o koncepcji przygotowania definicji zmiennej do polecenia:
FOO=bar somecommand someargs
To działa ... w pewnym sensie. Nie działa, gdy zmieniasz zmienną LC_ * (która wydaje się wpływać na polecenie, ale nie jego argumenty, na przykład zakresy znaków „[az]”) lub gdy przekazujesz dane wyjściowe do innego polecenia w ten sposób:
FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO
Mogę również dodać somecommand2 z „FOO = bar”, co działa, ale dodaje niechciane powielanie i nie pomaga w argumentach interpretowanych w zależności od zmiennej (na przykład „[az]”).
Więc jaki jest dobry sposób, aby to zrobić na jednej linii?
Myślę o czymś w kolejności:
FOO=bar (somecommand someargs | somecommand2) # Doesn't actually work
Mam wiele dobrych odpowiedzi! Celem jest utrzymanie tego jednowarstwowego, najlepiej bez użycia „eksportu”. Metoda wykorzystująca wywołanie Basha była ogólnie najlepsza, chociaż wersja w nawiasach z „eksportem” była nieco bardziej zwarta. Interesująca jest również metoda przekierowania zamiast potoku.
źródło
(T=$(date) echo $T)
zadziałaOdpowiedzi:
źródło
somecommand
sudo, musisz przekazać-E
flagę sudo, aby przejść przez zmienne. Ponieważ zmienne mogą wprowadzać podatności. stackoverflow.com/a/8633575/1695680FOO_X=foox bash -c 'echo $FOO_X'
działa zgodnie z oczekiwaniami, ale przy określonych nazwachDYLD_X=foox bash -c 'echo $DYLD_X'
zmiennych nie działa: echo puste. oba działająeval
zamiastbash -c
Co powiesz na eksportowanie zmiennej, ale tylko w podpowłoce ?:
Keith ma rację, aby bezwarunkowo wykonać polecenia, wykonaj następujące czynności:
źródło
;
raczej niż&&
; nie ma mowy,export FOO=bar
żeby upadł.&&
wykonuje lewe polecenie, a następnie wykonuje prawe polecenie tylko wtedy, gdy lewe polecenie się powiodło.;
wykonuje oba polecenia bezwarunkowo. Odpowiednikiem batch (cmd.exe
) systemu Windows;
jest&
.(FOO=XXX ; echo FOO=$FOO) ; echo FOO=$FOO
dajeFOO=XXX\nFOO=\n
.source
(aka.
) w takim przypadku? Ponadto, backtyki nie powinny być już używane w dzisiejszych czasach i jest to jeden z powodów, dla których używanie$(command)
jest bezpieczniejsze.bash
ale może być czymś innym, np.dash
) I nie mam żadnych problemów, jeśli muszę użyć cudzysłowów w ramach polecenia args (someargs
).Możesz także użyć
eval
:Ponieważ odpowiedź na to pytanie
eval
nie wydaje się wszystkim podobać, pozwólcie, że coś wyjaśnię: w przypadku użycia w formie pisemnej z pojedynczymi cytatami jest całkowicie bezpieczna. Jest dobry, ponieważ nie uruchomi zewnętrznego procesu (jak zaakceptowana odpowiedź) ani nie wykona poleceń w dodatkowej podpowłoce (jak druga odpowiedź).Ponieważ otrzymujemy kilka regularnych widoków, prawdopodobnie dobrze jest dać alternatywę
eval
, która zadowoli wszystkich i ma wszystkie zalety (a może nawet więcej!) Tej szybkiejeval
„sztuczki”. Po prostu użyj funkcji! Zdefiniuj funkcję za pomocą wszystkich poleceń:i wykonaj go ze swoimi zmiennymi środowiskowymi, takimi jak to:
źródło
eval
.eval
jest złem, nie rozumiejąc, o co mu chodzieval
. A może tak naprawdę nie rozumiesz tej odpowiedzi (i naprawdę nie ma w tym nic złego). Na tym samym poziomie: czy powiedziałbyś, żels
to źle, bofor file in $(ls)
jest źle? (i tak, nie głosowałeś zaakceptowanej odpowiedzi i nie zostawiłeś komentarza). SO jest czasem tak dziwnym i absurdalnym miejscem.eval
eval
brzmisz jak facet, który kiedyś czytał, jest złem, nie rozumiejąc, co jest złego , odnoszę się do twojego zdania: w tej odpowiedzi brakuje wszystkich ostrzeżeń i wyjaśnień koniecznych przy mówieniueval
.eval
nie jest zły ani niebezpieczny; nie więcej niżbash -c
.eval
. W podanej odpowiedzi argumenty zostały cytowane pojedynczo, chroniąc przed zmienną ekspansją, więc nie widzę problemu z odpowiedzią.eval
ogólnie rzecz biorąc, jest to kwestia bezpieczeństwa (podobna,bash -c
ale mniej oczywista), więc o zagrożeniach należy wspomnieć w odpowiedzi proponującej jej użycie. Nieostrożni użytkownicy mogą wziąć odpowiedź (FOO=bar eval …
) i zastosować ją do swojej sytuacji, aby stwarzała problemy. Ale oczywiście dla osoby odpowiadającej ważniejsze było ustalenie, czy głosowałem za jego i / lub innymi odpowiedziami, niż cokolwiek ulepszyć. Jak pisałem wcześniej, uczciwość nie powinna być głównym zmartwieniem; bycie nie gorszym niż jakakolwiek inna odpowiedź również jest nieważne.Zastosowanie
env
.Na przykład
env FOO=BAR command
. Pamiętaj, że zmienne środowiskowe zostaną przywrócone / niezmienione pocommand
zakończeniu wykonywania.Uważaj tylko na substytucję powłoki, tzn. Jeśli chcesz
$FOO
jawnie odwoływać się do tego samego wiersza poleceń, być może będziesz musiał uciec przed nią, aby interpreter powłoki nie wykonał podstawienia przed uruchomieniemenv
.źródło
Użyj skryptu powłoki:
źródło
export
; w przeciwnym razie$FOO
będzie zmienną powłoki, a nie zmienną środowiskową, a zatem nie będzie widoczna dlasomecommand
lubsomecommand2
.