@ jw013 Dobra uwaga i świetne artykuły. Podoba mi się cytat „Zmienne przechowują dane, funkcje przechowują kod”. z pierwszego linku, ale na mój użytek, dane podane funkcji (w tym przypadku at) to kod. Czy masz jakieś wskazówki na temat bezpieczniejszego sposobu organizowania / zbierania kodu at?
Cory Klein
atprzyjmuje shskładnię jako dane wejściowe. W ten sposób generowanie danych wejściowych atoznacza generowanie poprawnej, poprawnie cytowanej shskładni z dowolnych danych wejściowych, co nie jest trywialne, więc starałbym się tego unikać, jeśli to w ogóle możliwe. Byłoby naprawdę pomocne, gdybyś mógł podać trochę więcej szczegółów na temat tego, co próbujesz osiągnąć.
jw013
Przepraszam, nie chciałem rozpraszać się zbyt dużą ilością szczegółów, ale to, co robię, nie jest tak naprawdę skomplikowane, IMO. Tworzę skrypt, który wymaga „czasu” i „wiadomości”. Następnie działa atprzez określony „czas” i każe aturuchomić polecenie dzen2. dzen2pobiera „wiadomość” ze standardowego wejścia, a także wykorzystuje inne parametry statyczne. Trudność polega na tym, że muszę przesłać parametr „message” od użytkownika do dzen2polecenia, ale tak naprawdę nie uruchamiam dzen2się, mówię atto zrobić.
Należy również zauważyć, że cytaty są oceniane inaczej; podwójne cudzysłowy („) pozwalają na ocenę załączonego ciągu, pojedyncze cudzysłowy (') drukują ciąg jako literał. Przykład: "$(ls)"i '$(ls)'. To jest powód, dla którego cytaty pojawiają się w przykładach oryginalnych pytań.
Joseph Kern
Tablica jest również źródłem problemów. Kod należy do funkcji, dane do zmiennych. Prezentowany przykład działa tylko dlatego, że cudzysłowy są usuwane w podziale tablicy. A printf '<%s> ' "${VAR[@]}"pokaże, że cytaty zostały już usunięte. Jeśli ustawisz VAR tak, VAR=(echo \"hi\")aby faktycznie zawierał cytaty, ten sam problem pojawi się ponownie, $ ${VAR[@]}wydrukuje"hi"
9
Usuwanie cytatów następuje tylko w przypadku oryginalnych słów wejściowych, a nie w wyniku rozwinięć. Cytaty będące częścią zmiennych rozszerzonych pozostają nietknięte.
Jeśli cofniesz się nieco, zobaczysz, dlaczego podstawienie zmiennej absolutnie powinno zachować cudzysłowy.
Celem cudzysłowów w powłoce Unix / Linux / BSD jest trzymanie razem kawałków łańcucha, które inaczej zostałyby przeanalizowane jako wiele łańcuchów. Ponieważ domyślnie powłoka używa białych znaków jako separatora tokenów, ciąg znaków ze spacjami (np. „Jeden dwa trzy”), jeśli nie zostanie cytowany lub nie zostanie w żaden sposób poprzedzony znakiem ucieczki, zostanie sparsowany jako 3 łańcuchy: „jeden”, „dwa” i „trzy”.
Jeśli programista chce łańcucha z wartością interpolowanej zmiennej:
VAR=two
STRING="one $VAR three"
powłoka absolutnie nie powinna usuwać cudzysłowów: ciąg zawierający spacje zostałby przeanalizowany jako 3 mniejsze ciągi.
eval
jest toat
) to kod. Czy masz jakieś wskazówki na temat bezpieczniejszego sposobu organizowania / zbierania koduat
?at
przyjmujesh
składnię jako dane wejściowe. W ten sposób generowanie danych wejściowychat
oznacza generowanie poprawnej, poprawnie cytowanejsh
składni z dowolnych danych wejściowych, co nie jest trywialne, więc starałbym się tego unikać, jeśli to w ogóle możliwe. Byłoby naprawdę pomocne, gdybyś mógł podać trochę więcej szczegółów na temat tego, co próbujesz osiągnąć.at
przez określony „czas” i każeat
uruchomić poleceniedzen2
.dzen2
pobiera „wiadomość” ze standardowego wejścia, a także wykorzystuje inne parametry statyczne. Trudność polega na tym, że muszę przesłać parametr „message” od użytkownika dodzen2
polecenia, ale tak naprawdę nie uruchamiamdzen2
się, mówięat
to zrobić.Odpowiedzi:
Dodatkowa para cytatów zostanie wykorzystana tylko w dodatkowym etapie oceny. Na przykład wymuszony przez
eval
:Ale ogólnie rzecz biorąc, złym pomysłem jest umieszczanie poleceń z parametrami w jednym ciągu. Zamiast tego użyj tablicy:
źródło
"$(ls)"
i'$(ls)'
. To jest powód, dla którego cytaty pojawiają się w przykładach oryginalnych pytań.printf '<%s> ' "${VAR[@]}"
pokaże, że cytaty zostały już usunięte. Jeśli ustawisz VAR tak,VAR=(echo \"hi\")
aby faktycznie zawierał cytaty, ten sam problem pojawi się ponownie,$ ${VAR[@]}
wydrukuje"hi"
Usuwanie cytatów następuje tylko w przypadku oryginalnych słów wejściowych, a nie w wyniku rozwinięć. Cytaty będące częścią zmiennych rozszerzonych pozostają nietknięte.
źródło
Jeśli cofniesz się nieco, zobaczysz, dlaczego podstawienie zmiennej absolutnie powinno zachować cudzysłowy.
Celem cudzysłowów w powłoce Unix / Linux / BSD jest trzymanie razem kawałków łańcucha, które inaczej zostałyby przeanalizowane jako wiele łańcuchów. Ponieważ domyślnie powłoka używa białych znaków jako separatora tokenów, ciąg znaków ze spacjami (np. „Jeden dwa trzy”), jeśli nie zostanie cytowany lub nie zostanie w żaden sposób poprzedzony znakiem ucieczki, zostanie sparsowany jako 3 łańcuchy: „jeden”, „dwa” i „trzy”.
Jeśli programista chce łańcucha z wartością interpolowanej zmiennej:
powłoka absolutnie nie powinna usuwać cudzysłowów: ciąg zawierający spacje zostałby przeanalizowany jako 3 mniejsze ciągi.
źródło