Postanowiłem dać Zsh szansę na przeciw Bashowi i natknąłem się na jakieś nieprzyzwoite zachowanie, o którym nie mogłem znaleźć niczego w sieci:
Jeśli wykonasz a ls | grep foo
w Bash, ls
tylko jeden plik w wierszu, więc wyświetla grep
tylko pasujące pliki. Wydaje się, że gdzieś (a ponieważ nie mogłem znaleźć niczego w konfiguracji, myślę, że musi to być sam kod Bash), -1
opcja jest przekazywana do ls
.
zsh jednak nie robi tej magii: jeśli przejdziesz ls
bez dalszych opcji grep
, to właśnie to zrobi, a także otrzymasz wyniki, które przypadkowo pojawiły się w tej samej linii jako dopasowanie.
Mój pomysł na osiągnięcie zachowania Bash w zsh polegałby na wykryciu, czy dane ls
wyjściowe zostaną wprowadzone do potoku grep
i zdefiniowaniu czegoś takiego jak alias dla takich przypadków. Ale nie jestem pewien, jak i czy to w ogóle możliwe.
Aktualizacja: Jak pokazują poniższe Larki, Bash nie robi tutaj nic specjalnego i tak naprawdę ls
powinno działać w ten sposób, jeśli dane wyjściowe nie trafią do terminala.
Niemniej jednak oto co się ze mną dzieje:
> ls
a b c d e f g h
bash$ ls | grep b
b
zsh> ls | grep b
a b c d e f g h
Udało mi się to odtworzyć na Ubuntu 11.10 z zsh 4.3.11 i GNU coreutils 8.5, a także na maszynie Debian Squeeze z zsh 4.3.10.
Aktualizacja 2: Badając nieco więcej, dowiedziałem się, że ten błąd pojawia się tylko wtedy, gdy plik grml .zshrc jest aktywny. Musi tam być coś, co otwiera terminal dla wyjścia, jeśli jest on potokowany. Czy ktoś wie, czego szukać?
ls
jest uważane za złą praktykęOdpowiedzi:
Zgodnie z
ls
dokumentacją takie zachowanie jest nieodłączne odls
polecenia:Podczas przesyłania do innego procesu za pomocą
|
,stdout
nie powinno być tty.bash
nie robi nic specjalnego.We wszystkich moich testach korzystanie z
zsh
wersji 4.3.15 w systemie Linux izsh
4.3.11 w systemie OS Xls
zachowuje się tak samozsh
jak podbash
. Jeśli naprawdę uważasz, że widzisz inne zachowanie, zaktualizuj swoje pytanie o (a) używaną wersjęzsh
i (b) pełny przykład problemu, pokazujący zarówno rzeczywistą zawartość katalogu, jak i konkretną linię poleceń, którą „ ponownie używam.źródło
Zawężając się do linii odpowiedzialnej
.zshrc
, mogłem sam to zrozumieć:Jest to w rzeczywistości o wiele prostsze niż wirtualny terminal do pipingu. Błąd wynika z wiersza 1477 konfiguracji grml, który wygląda następująco:
Więc
ls
polecenie oczywiście nie jest wywoływane bezpośrednio, ale poprzez alias. I to wyraźnie aktywuje wyjście kolumny za pomocą-C
opcji.źródło