Próbuję oglądać liczbę plików w moim /tmp/
katalogu. W tym celu myślałem, że to polecenie zadziała:
watch sh -c 'ls /tmp/|wc -l'
Ale wydaje się, że działa tak, jakby ls
nie miał żadnych argumentów. Mianowicie, jestem w ~
środku i zamiast tego otrzymuję tam liczbę plików /tmp/
. Znalazłem obejście, które wydaje się działać:
watch sh -c 'ls\ /tmp/|wc -l'
Ale dlaczego muszę uciec z przestrzeni między ls
i /tmp/
? W jaki sposób polecenie jest przekształcane, watch
aby ls
dane wyjściowe były podawane do wc
, ale /tmp/
nie były przekazywane jako argument do ls
?
watch "sh -c 'ls /tmp | wc -l'"
Wykonanie tego polecenia powinno uzyskać pożądany efekt. To nie jest wina, spróbuj,sh -c ls /tmp
a dostaniesz swój katalog domowy (ale nie mam pojęcia, dlaczego ...)watch
niewłaściwie .Powierzchnia polecenie, które przechodzą dowatch
z kolei jest zasilany przezwatch
dosh -c
, więc jesteś w efekcie robish -c
dwa razy./tmp
Jest to argument, abysh
w tym przypadku nie argumentowaćls
.Odpowiedzi:
Różnicę można zobaczyć poprzez
strace
:W przypadku cudzysłowu
ls /tmp
jest przekazywany jako pojedynczy argument-c
dosh
, który działa zgodnie z oczekiwaniami. Bez tego cudzysłowu polecenie jest zamiast tego dzielone na słowa podczaswatch
uruchamiania,sh
które z kolei uruchamia dostarczonąsh
, tak żels
jest przekazywany tylko jako argument do-c
, co oznacza, że podrzędny podrzędnysh
uruchomi tylko nagiels
polecenie i wyświetla zawartość bieżącego działania informator.Dlaczego więc komplikacja
sh -c ...
? Dlaczego po prostu nie uruchomićwatch 'ls /tmp|wc -l'
?źródło
strace
tym.ls /tmp
to ...” i „Bez tej backquote , polecenie to ...” i używabq
inobq
jak nazwy plików, kiedy cały czas odnosząc się do backslashem w swojejls\ /tmp
komendzie.Istnieją dwie główne kategorie
watch
poleceń (z tych, które mają być uruchamiane okresowo,watch
nie jest to standardowe polecenie, są nawet systemy, w którychwatch
działa coś zupełnie innego, jak szpiegowanie w innej linii tty we FreeBSD).Jeden, który już przekazuje konkatenację swoich argumentów ze spacjami do powłoki (faktycznie wywołuje
sh -c <concatenation-of-arguments>
) i taki, który po prostu uruchamia polecenie określone z podanymi argumentami bez wywoływania powłoki.Jesteś w pierwszej sytuacji, więc potrzebujesz tylko:
Kiedy to zrobisz:
Twój
watch
faktycznie działa:I
sh -c ls /tmp/
uruchamials
skrypt wbudowany gdzie$0
jest/tmp/
(takls
jest uruchamiany bez argumentów i wyświetla bieżący katalog).Niektóre
watch
implementacje z pierwszej kategorii (jak ta z procps-ng w Linuksie) akceptują-x
opcję, aby zachowywały się jakwatch
z drugiej kategorii. Dzięki temu możesz:źródło