SSH를 통한 zmv(zsh)는 쉘과 스크립트 간에 다르게 동작합니다.

SSH를 통한 zmv(zsh)는 쉘과 스크립트 간에 다르게 동작합니다.

zmvSSH를 통해 스크립트에서 예상대로 작동하도록 도움을 주시면 정말 감사하겠습니다 .

내가 완전히 제어할 수 있는 원격 서버의 파일 이름을 변경하려고 합니다. 로컬 및 원격 시스템 모두 macOS 10.14.6을 실행하고 있으며 zsh를 기본 셸로 사용합니다.

zsh 터미널 창을 열고 ssh를 통해 연결하고 을 입력하면 zmv '(xxx_)(*)' 'yyy_$2'예상대로 작동합니다. 하지만 zmv를 ssh에 넣으면 스크립트로 패키징해야 한다고 가정합니다.

ssh me@myserver "cd /Users/me/mypath; autoload zmv; zmv '(xxx_)(*)' 'yyy_$2'"

zmv가 모든 파일 쌍에 대해 "yyy_에 매핑됩니다"라고 말하기 때문에 실패합니다. 즉, 일치하는 그룹을 인식하지 못하거나 역참조가 작동하지 않는 것입니다.

autoload zmv저는 zsh와 ssh가 서로 다른 두 가지 유형의 쉘이고 서로 다른 환경을 가지고 있다는 것을 이해합니다. 예를 들어 원격 시스템의 .zshrc에 있더라도 그렇게 해야 한다는 것을 알았습니다 . 추가(다시 .zshrc에 설정)를 시도했고 noglob zmv여러 가지를 이스케이프 처리해 보았습니다.

나는 또한 zmv -w-W옵션을 시도했습니다. 이 -W옵션은 잘못되지 않는 유일한 옵션이므로 예를 들어 다음과 같이 할 수 있습니다.

ssh me@myserver "cd /Users/me/mypath; autoload zmv; zmv -n -W 'xxx_*_*_*.*' '*-*-*.*'"

효과가있다. 그러나 대체 그룹 중 하나를 생략하면 *zmv는 "오류: 각 패턴의 와일드카드 수가 일치해야 합니다"라고 말합니다. 이는 원래 파일 이름의 일부를 생략하려고 할 때 별로 도움이 되지 않습니다.

어떻게 해야 합니까?

답변1

여기서 문제는 참조에 있으며 zsh 또는 zmv에만 국한되지 않습니다.

당신의 명령에 따라

ssh me@myserver "cd /Users/me/mypath; autoload zmv; zmv '(xxx_)(*)' 'yyy_$2'"

$2"약한" 외부 큰따옴표는 로컬 쉘이 (아마도 비어 있는) 위치 인수로 확장되는 것을 막지 않습니다 $2. 따라서 원격 쉘이 보는 것은 다음과 같습니다.

cd /Users/me/mypath; autoload zmv; zmv '(xxx_)(*)' 'yyy_'

두 파일이 일치 하면 (xxx_)(*)zmv는 파일 이름을 다음으로 바꾸려고 시도하여 yyy_오류가 발생합니다 .both map to yyy_

대체 버전(스위치로 활성화)에서 와일드카드 모드가 있는 버전은 -W동일한 문제를 겪지 않습니다. 와일드카드(셸 전역 변수)는 큰따옴표 내에서도 확장되지 않기 때문입니다.

$2문제를 해결하는 가장 간단한 방법은 간섭 없이 원격 셸에 전달할 또 다른 참조 계층을 추가하는 것입니다 .

ssh me@myserver "cd /Users/me/mypath && autoload zmv && zmv '(xxx_)(*)' 'yyy_\$2'"

또한 실패할 경우 실행 하고 싶지 않기 때문에 여기에서 &&대신 사용하십시오. 그렇지 않으면 홈 디렉토리의 파일 이름이 바뀌게 됩니다 .;zmvcdmemyserver

여기 문서를 사용한 대체 해결 방법을 포함하여 참조 및 SSH 문제에 대한 보다 일반적인 논의는 관련 문제를 참조하세요.

관련 정보