Używanie symboli wieloznacznych w poleceniach z zsh


39

Używając poleceń takich jak rsynci scpprzy pomocy ZSH, mam problemy. Zamiast (normalnego) zachowania polegającego na podawaniu mi wszystkich pasujących plików, nie uruchomi się i zwróci:

  ~  rsync -azP user@server:~/* ~/
zsh: no matches found: user@server:~/*

Jak mogę to naprawić?

Mój .zshrc

ZSH=$HOME/.oh-my-zsh
ZSH_THEME="robbyrussell"
plugins=(git brew)
source $ZSH/oh-my-zsh.sh
export PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/local/sbin

Odpowiedzi:


50

Jest to związane ze sposobem, w jaki ZSH zarządza znakami globowania w celu generowania nazw plików. Domyślnie ZSH generuje nazwy plików i generuje błąd przed wykonaniem polecenia, jeśli nie znajdzie pasujących elementów.

Istnieje wiele sposobów obejścia tego zachowania, oto niektóre z nich:

  • Najszybszym jest umieszczenie globbing znaków w cudzysłowie.
$ rsync -azP "user@server:~/*" ~/
  • Aby wprowadzić trwałą zmianę, musisz dodać w swoim .zshrcpliku:
unsetopt nomatch

Zapobiegnie to drukowaniu przez ZSH błędu, gdy nie można znaleźć dopasowania.

  • Inną możliwością jest wyłączenie globowania dla konkretnego polecenia za pomocą noglobmodyfikatora polecenia. Ustawiając alias .zshrcna przykład:
alias scp='noglob scp'

Dzięki! Nigdy nie musiałem tego robić bash.
Morgan

@ Organ To dziwne. Bez cytatów Bash powinien rozwinąć tyldę, zanim rsyncją zobaczy. Czy to możliwe, że korzystałeś z tej samej ścieżki do katalogu domowego na obu serwerach?
slhck 18.04.13

@slhck Nie, ma rację. Zsh ma jeszcze kilka opcji konfiguracji symboli wieloznacznych, więc to zachowanie można zmienić w Zshrc.
Spack

1
@ sa125 Zredagowałem swoją odpowiedź.
Spack

1
@slhck: bashrozwija tyldę tylko wtedy, gdy zaczyna słowo, lub jest pierwszym znakiem po znaku :lub =w przypisaniu zmiennej. W przeciwnym razie traktowane jest dosłownie.
chepner

8

Używam zpretzo od kilku miesięcy, a także ten problem. Natrafiłem na fajne i przydatne rozwiązanie, jeśli nie chcesz wprowadzać żadnych zmian: po prostu wstaw ukośnik odwrotny do polecenia.

~/p/b/a/files ❯❯❯ scp *.* myserver@host:~/
*.*: No such file or directory

~/p/b/a/files ❯❯❯ \scp *.* myserver@host:~/
jquery.min.js                              100%   93KB  92.6KB/s   00:00
json2.min.js                               100%   3377   3.3KB/s   00:00

Mam nadzieję, że to pomoże!


Świetne rozwiązanie !!
rok

Idealnie, działało to dla mnie świetnie na OSX!
sMyles

Niesamowite!! Ale jakiś powód, dlaczego / jak to działa?
Kannan Ramamoorthy

3

To rozwiązuje problem bez konieczności ręcznego cytowania adresów URL

autoload -U url-quote-magic  
zle -N self-insert url-quote-magic

# sort it out for SCP
some_remote_commands=(scp rsync)
zstyle -e :urlglobber url-other-schema \
  '[[ $some_remote_commands[(i)$words[1]] -le ${#some_remote_commands} ]] && reply=("*") || reply=(http https ftp)'

A to idzie w .zshrc?
Morgan

tak, to wchodzi w twoją konfigurację zsh. FWIW, po prostu uruchom nową powłokę ( zsh -fdla kanonicznego conf powłoki), skopiuj i wklej polecenia w swojej powłoce i wpisz (lub wklej) swoje rsyncpolecenie. Zobaczysz magię w pracy ;-) (specjalne znaki pod adresem URL zostaną automatycznie zacytowane)
Francisco

powinieneś zaakceptować moją odpowiedź: - P jest to o wiele lepsze niż cytowanie lub wyłączanie globowania dla całego polecenia.
Francisco,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.