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
Morgan
źródło

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'
Spack
źródło
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!

superuseroi
źródło
Ś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)'
Francisco
źródło
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,