Catalina가 Bash 대신 Zsh로 기본 설정 한다는 소식을 듣고 저는 스위치에 대해 알려주는 많은 결과를 찾았고 셸 스크립트에 문제를 일으킬 수 있지만 Zsh에 익숙하지 않아 이러한 문제가 무엇인지 알 수 없습니다.
내 셸 스크립트는 실제로 그렇지 않습니다. 그렇게 복잡하지만 저는 macOS와 Linux에서만 Bash를 사용했습니다. Zsh에 대한 경험이 전혀 없습니다. 누구든지 간단한 실용적인 비교를 제공하거나 제가 알아야 할 특정 걸림돌을 제공 할 수 있습니까? Catalina가 출시 될 때 새 셸?
댓글
답변
먼저 중요한 사항 :
- Bash는 “없어지지 않습니다. . 이미 bash를 사용하고 있다면 아무것도 변경되지 않습니다. 변경된 것은 zsh가 새 계정의 기본 로그인 셸이된다는 것입니다. 그런 경우에도 대신 bash를 선택할 수 있습니다.
- 스크립트는 영향을받지 않습니다 . 대화식 사용을위한 쉘, 즉 터미널의 쉘 (및 crontabs와 같은 로그인 쉘을 사용하는 몇 가지 다른 것들)이 변경되었습니다. 실행 권한이있는 파일에 shebang 줄 (예 :
#!/bin/bash
또는#!/bin/sh
또는#!/usr/bin/env bash
, “이전과 동일하게 계속 작동합니다. - Zsh”의 구문은 bash와 완전히 호환되지 않습니다. 하지만 거의 비슷합니다. 예를 들어 일반적인 별칭 및 함수와 같은 많은 코드가 계속 작동합니다. 주요 차이점은 대화 형 구성 기능에 있습니다.
이제 전환을 고려하고 있다고 가정합니다. 수년 동안 가능성이 있었던 zsh 로의 주요 차이점은 다음과 같습니다. 이것은 완전한 목록이 아닙니다!
대화식 사용의 주요 차이점
구성 파일 : bash 읽기 (주로) .bashrc
비 로그인 대화 형 셸 (그러나 macOS는 기본적으로 터미널에서 로그인 셸을 시작 함), .profile
또는 및 .inputrc
. Zsh 읽기 (주로) .zshrc
(모든 대화 형 셸에서) 및 .zprofile
(로그인 쉘에서). 이는 bash 사용자 정의가 적용되지 않음을 의미합니다. “포팅해야합니다. 많은 부분을 조정해야하므로 파일을 복사 할 수 없습니다.
키 바인딩 은 완전히 다른 구문을 사용합니다. Bash는 .inputrc
및 bind
내장 을 사용하여 키를 readline 명령 . Zsh는 bindkey
내장 을 사용하여 키를 zle 위젯에 바인딩합니다. . 대부분의 readline 명령은 zsh와 동일하지만 항상 완벽한 것은 아닙니다.
키 바인딩에 대해 말하면, Vi (m)을 터미널 편집기로 사용하지만 쉘에서 명령 줄 모드로 사용하지 않는 경우 “EDITOR
또는 VISUAL
는 vi
또는 vim
로 설정됩니다. . bindkey -e
는 emacs 모드로 전환합니다.
프롬프트 : bash는 PS1
에서 백 슬래시 이스케이프 . Zsh는 주로 iv id = “865634faa8을 포함하는 PS1
에서 프롬프트를 설정합니다. “>
퍼센트 이스케이프 . bash의 PROMPT_COMMAND
의 기능은 precmd
및 후크 기능 . Zsh에는 프롬프트 테마 메커니즘 을 포함하여 멋진 프롬프트를 구축 할 수있는 더 편리한 메커니즘이 있습니다.
기본 명령 줄 기록 메커니즘 ( 위쪽 / 아래쪽 탐색, Ctrl +로 검색) R , !!
및 친구들과의 역사 확장, Alt + 로 마지막 인수 회상. 또는 $_
)는 동일한 방식으로 작동하지만 세부 사항에 많은 차이가있어서 여기에 나열하기에는 너무 많습니다. 파일 형식을 변경하는 셸 옵션을 변경하지 않은 경우 .bash_history
를 .zsh_history
에 복사 할 수 있습니다.
완료 : 두 셸 모두 기본적으로 대부분 명령과 파일 이름을 완료하는 기본 완료 모드로 설정되고 다음을 통해 고급 모드로 전환됩니다. bash에서 bash_completion
를 포함하거나 zsh에서 compinit
를 실행합니다. bash가 더 잘 처리하는 명령과 zsh가 더 잘 처리하는 명령을 찾을 수 있습니다. Zsh는 일반적으로 더 정확하지만 때로 bash가 “올바르지 않지만 합리적인 작업을 수행하는 곳을 포기합니다. 명령에 대해 가능한 완료를 지정하기 위해 zsh에는 다음 세 가지 메커니즘이 있습니다.
- 잊을 수있는
compctl
가있는 “이전”완료 메커니즘입니다. -
compadd
및 밑줄로 시작하는 많은 함수를 사용하는”새로운 “완료 메커니즘 및 강력하지만 복잡한 사용자 구성 메커니즘 . - 에뮬레이션
bashcompinit
를 실행하여 활성화 할 수있는 bash 완료 기능을 지원합니다 . 에뮬레이션은 100 % 완벽하지는 않지만 일반적으로 작동합니다.
많은 bash의 shopt
설정 에 해당하는 이 있습니다. zsh의 setopt
Zsh doe 기본적으로 스크립트에서만 #
를 명령 줄에서 주석 시작으로 취급하지 않습니다 (.zshrc
등 포함). 대화 형 댓글을 사용하려면 setopt interactive_comments
를 실행하세요.
스크립팅의 주요 차이점
(물론 명령 줄을 사용하는 고급 사용자의 경우)
bash에서 $foo
는 foo
는 공백 문자로 분할하고 공백으로 구분 된 각 부분에 대해 와일드 카드 문자를 포함하고 기존 파일과 일치하는 경우 패턴을 일치 목록으로 바꿉니다. foo
의 값만 얻으려면 "$foo"
가 필요합니다. 명령 대체 $(foo)
에도 동일하게 적용됩니다. zsh에서 $foo
는 foo
의 값이고 $(foo)
는
두 가지 예외를 제외하고 최종 줄 바꿈을 뺀 값입니다. 인용되지 않은 비어있는 변수를 확장하여 단어가 비어 있으면 제거됩니다 (예 :a=; b=; printf "%s\n" one "$a$b" three $a$b five
는one
, 빈 줄,three
,five
). 인용되지 않은 명령 대체의 결과는 공백으로 분할되지만 조각은 와일드 카드 일치를 거치지 않습니다.
배시 배열 은 0에서 (길이 -1)까지 색인이 지정됩니다. Zsh 배열은 1부터 길이까지 인덱싱됩니다. a=(one two three)
의 경우 bash에서는 ${a[1]}
가 two
이지만 zsh에서는 one
. bash에서 중괄호없이 배열 변수 만 참조하면 첫 번째 요소가 표시됩니다. 예를 들어 $a
는 one
및 $a[1]
는 one[1]
입니다.zsh에서 $a
는 비어 있지 않은 요소 목록으로 확장되고 $a[1]
는 첫 번째 요소로 확장됩니다. 마찬가지로 bash에서 배열의 길이는 ${#a}
입니다. 이것은 zsh에서도 작동하지만 $#a
로 더 간단하게 작성할 수 있습니다. setopt ksh_arrays
를 사용하여 0- 인덱싱을 기본값으로 설정할 수 있습니다. 이렇게하면 배열 요소를 참조하기 위해 중괄호를 사용해야한다는 요구 사항도 설정됩니다.
배시에는 추가 가 있습니다. foo
또는 iv id와 일치하는 @(foo|bar)
와 같은 와일드 카드 패턴 = “61a2882151”> : shopt -s extglob
에서만 사용 설정됩니다. zsh에서는 setopt ksh_glob
를 사용하여 이 패턴 을 활성화 할 수 있지만 더 간단한 유형의 네이티브 구문 (예 : (foo|bar)
). 일부는 setopt extended_glob
가 필요합니다. 이를 .zshrc
에 넣으면 완료 기능에서 기본적으로 켜져 있습니다.) 재귀 디렉토리 탐색을위한 **/
는 항상 zsh에서 활성화됩니다.
bash에서는 기본적으로 와일드 카드 패턴이 어떤 파일과도 일치하지 않으면 그대로 남습니다. 변하지 않은. zsh에서는 기본적으로 “오류가 발생하며 이는 일반적으로 가장 안전한 설정입니다. 와일드 카드 매개 변수를 명령에 전달하려면 따옴표를 사용하십시오. setopt no_nomatch
. setopt null_glob
.
bash에서 파이프 라인의 오른쪽은 서브 쉘에서 실행됩니다. zsh에서는 상위 쉘에서 실행되므로 somecommand | read output
와 같은 것을 작성할 수 있습니다.
몇 가지 멋진 zsh 기능
다음은 bash에없는 멋진 zsh 기능입니다 ( 적어도 심각한 팔꿈치 그리스 없이는 아닙니다). 다시 한번 말씀 드리지만, 이것은 제가 가장 유용하다고 생각하는 것 중 일부일뿐입니다.
Glob 한정자 시간 스탬프, 크기 등과 같은 메타 데이터를 기반으로 파일을 일치시킬 수 있습니다. 또한 출력을 조정할 수도 있습니다. 구문은 다소 모호하지만 매우 편리합니다. 다음은 몇 가지 예입니다.
-
foo*(.)
:foo*
및 일반 파일에 대한 심볼릭 링크 (디렉토리 및 기타 특수 파일 제외) -
foo*(*.)
:.
-
foo*(-.)
: 기호 링크가 아닌foo*
와 일치하는 일반 파일 만 및 기타 특수 파일. -
foo*(-@)
:foo*
와 일치하는 매달린 기호 링크 만. -
foo*(om)
:foo*
와 일치하는 파일, 마지막 수정 날짜순으로 정렬 됨, 가장 최근 날짜부터.ls
, 자체 정렬을 수행합니다. 특히 유용합니다… -
foo*(om[1,10])
:foo*
와 일치하는 가장 최근 파일 10 개, 가장 최근 파일부터. -
foo*(Lm+1)
: 크기가 1MB 이상인foo*
와 일치하는 파일. -
foo*(N)
:foo*
와 동일하지만 이것이 어떤 파일과도 일치하지 않으면 빈 목록을 생성합니다.null_glob
옵션의 설정 (위 참조). -
*(D)
: 도트 파일 (.
및..
제외). -
foo/bar/*(:t)
( 기록 수정 자 ) :foo/bar
에있는 파일이지만 파일의 기본 이름 만 포함합니다. 예 :foo/bar/qux.txt
, “qux.txt
로 확장됩니다. -
foo/bar/*(.:r)
:foo/bar
에서 일반 파일을 가져 와서 확장자를 제거하십시오. 예 :foo/bar/qux.txt
는foo/bar/qux
로 확장됩니다. -
foo*.odt(e\""REPLY=$REPLY:r.pdf"\")
:foo*.odt
와 일치하는 파일 목록을 만들고.odt
를.pdf
로 바꿉니다 (PDF 파일이 있음).
다음은 몇 가지 유용한 zsh 관련 와일드 카드 패턴입니다. / a> .
-
foo*.txt~foobar*
: 모두.txt
이름이foo
로 시작하지만foobar
가 아닌 div> 파일. -
image<->.jpg(n)
: 기본 이름이image
뒤에 숫자가 오는 모든.jpg
파일 (예 :image3.jpg
및image22.jpg
(image-backup.jpg
제외). glob 한정자(n)
를 사용하면 파일이 숫자 순서로 나열됩니다. 즉,image9.jpg
가image10.jpg
(setopt numeric_glob_sort
를 사용하여-n
없이도이를 기본값으로 설정할 수 있습니다. a>).
대량 이름 바꾸기 파일 에 zsh는 매우 편리한 도구 : zmv
함수 . .zshrc
에 대한 제안 :
autoload zmv alias zcp="zmv -C" zln="zmv -L"
예 :
zmv "(*).jpeg" "$1.jpg" zmv "(*)-backup.(*)" "backups/$1.$2"
Bash에는 변수 값을 가져올 때 변환을 적용하는 몇 가지 방법이 있습니다 . Zsh에는 동일한 것과 더 많은 것 이 있습니다.
Zsh에는 디렉토리를 변경 할 수있는 몇 가지 편리한 기능이 있습니다. iv id = “4f0c71af90을 입력하지 않고 이름을 입력 할 때 디렉토리로 변경하려면 setopt auto_cd
를 켜십시오. “> (현재 bash에도이 기능이 있습니다). 2 인수 형식을 사용하여 cd
이름이 현재 디렉토리에 가까운 디렉토리로 변경할 수 있습니다. . 예를 들어 “/some/where/foo-old/deeply/nested/inside
에 있고 /some/where/foo-new/deeply/nested/inside
로 이동하려는 경우 cd old new
.
변수에 값을 할당하려면 물론 VARIABLE=VALUE
를 작성합니다. 수정하려면 대화식으로 변수의 값 은 vared VARIABLE
를 실행하면됩니다.
최종 조언
Zsh는 대소 문자를 구분하지 않는 완성과 같은 조리법을 포함하여 가장 일반적인 몇 가지 설정을 지원하는 구성 인터페이스와 함께 제공됩니다.이 인터페이스를 (재) 실행하려면 ( “zsh-newuser-install
에서 편집 한 구성 파일을 사용하는 경우 첫 번째 줄은 필요하지 않습니다.) :
autoload -U zsh-newuser-install zsh-newuser-install
즉시 구성 파일이 전혀없는 상태에서 1990 년대 버전과의 하위 호환성을 위해 zsh의 유용한 기능 중 상당수가 비활성화되었습니다. zsh-newuser-install
는 몇 가지 권장 기능을 사용하도록 제안합니다.
웹에는 zsh 구성 프레임 워크가 많이 있습니다 (대부분은 Github에서 ). 몇 가지 강력한 기능을 시작하는 편리한 방법이 될 수 있습니다. 동전의 뒷면은 종종 저자가하는 방식으로 일을하도록 당신을 묶어두기 때문에 때때로 “당신이 원하는 방식으로 일을하지 못하게 할 것입니다. 위험을 감수하고 사용하십시오.
The zsh 설명서에는 많은 정보가 있지만 “간결하고 따르기 어렵고 예제가 거의없는 방식으로 작성되는 경우가 많습니다. 주저하지 말고 온라인에서 설명과 예제를 검색하십시오. 설명서에서 이해하기 쉬운 zsh를 놓치게됩니다. 두 가지 좋은 리소스는 zsh-users 메일 링리스트 와 Unix Stack Exchange 입니다. Mac에서 zsh로 전환하는 방법에 대한 광범위한 기사 모음 은 scriptingosx.com 및 유용한 명령 기록을 가져 오는 Ruby 스크립트 는 Github에서 찾을 수 있습니다.
댓글
- 이제 ‘ 이제 놀라운 ctrl-o가 zsh에서 작동하는지 궁금합니다. 물론 bash의 Mac OS에서도 ‘ 작동하지 않으므로 ‘이 답변이나 사이트와 관련이 없습니다. ‘ 빠른 온라인 검색에서 zsh의 ctrl-o에 대한 정보를 찾을 수 없었지만 bash의 ctrl-o에 대한 정보도 일반적으로 정확하지 않습니다 …
- @Jasper 저는 ‘ bash가 이것을 가지고 있는지 몰랐습니다. 설명에 따르면 Co는 zsh에서 기본 키 바인딩을 사용하여 동일한 작업을 수행합니다.
- ” 몇 가지 멋진 zsh 기능을 포함하게되어 기뻤습니다. ” 섹션을 읽고 애타게 읽어보고 Apple이 극도로 일반적인 Bash에서 훨씬 덜 인기있는 Zsh로 전환하기로 결정한 이유를 이해하려고합니다. 나는 ‘ 원격에서 스위치를 정당화 할만한 어떤 것도 전혀 찾지 못했습니다. ‘ 분명히 완전하지 않은 목록이지만 Zsh의 헤드 라인 기능이 ‘ 명백해야하기 때문에 생략 했습니까? 내가 여기서 무엇을 놓치고 있니?
- @CodyGray 나는 ‘ 알지 못하고 Apple은 ‘ 습관이 없습니다. 자신을 정당화하는 것. 상황이 바뀌었다면 ‘ 좋은 bash 기능섹션이 없다는 사실과 관련이있을 수 있습니다.또는 GPLv3가 아닌 마지막 bash가 정말 오래되고 zsh는보다 자유로운 라이선스를 가지고 있기 때문일 수 있습니다.
- 내 이해는 라이센스가 본질적으로 유일한 이유였습니다. ‘ 또한 macOS의 bash가 여전히 v3 인 이유입니다. 길거리에서는 bash가 ‘ 업데이트되지 않았으며 최종 사용자가 brew 등을 통해 설치하지 않는 한 제거 될 것으로 예상됩니다. 내 계획은 macOS에서는 zsh가 더 빠르지 만, 당분간 Debian에서는 bash를 사용합니다.
답변
변경 셸을 지금 테스트하고 기다릴 필요가 없습니다.
chsh -s /bin/zsh
-
bash
구문은 여전히 bash를 찾아 호출합니다. - Mojave의 동일한 bash가 Catalina에서 제공되며 마이그레이션 된 사용자는 이전 셸을 유지합니다.
- 많은 블로그에 환경 설정 파일 이동에 대한 훌륭한 글이 있습니다. 여기에 해당 파일이 있습니다. https://scriptingosx.com/2019/06/moving-to-zsh-part-2-configuration-files/
- Armin은 블로그 시리즈를 약 22,000 단어로 된 적절한 책으로 만들었습니다 .
또한 macOS 사용자의 95 %가 명령 줄을 사용하지 않고 사용하는 사용자의 95 %가 중요한 내용이나 시간을 변경할 필요가 없다고 추정합니다. 모두. (쉘이 존재한다는 것을 알고있는 1 % 중 10 %가 .dot 파일에 몇 줄을 이식하는 것 외에 다른 작업을 수행해야한다는 점에 더 가깝습니다.)
프롬프트가 변경되며 bash
에서 프롬프트를 변경 한 경우 zsh
에서 프롬프트를 변경하는 방법이 더 어렵지 않고 문서화되어 있습니다. bash.
최신 포탄은 주요 아이템을 부수거나 적응 기간이 고통 스러울 경우 바닥에서 떨어지지 않습니다. 좀 더 근본적인 변화를 원하고 껍데기를 정말로 원하면 생각할 필요가 있고 채택 할 훈련과 의도가 필요합니다. 물고기 를 사용해보세요.
댓글
-
fish
와 충돌합니다. 나는 지금 2 년 동안 그것을 사용하지만 일부 복사 / 붙여 넣기 한 줄의 비 호환성은 피곤합니다. 반면에 매우 편리한 셸입니다 (< kbd > Tab < / kbd >는 훌륭합니다.) - 나는 물고기를 사랑하고 싶었지만 여전히 물고기를 사랑하고 싶지만 10 년 동안 너무 많은 껍데기를 가지고 있습니다.
ksh
에서 실제로 접어 볼 수있는 부분을 벗어나게합니다. 나는 기꺼이 bash를 뒤로하고 zsh를 개인적으로 완전히 받아 들일 것입니다. - 나는 물고기에 완전히 압도당했습니다. 실제로는 약간 덜 거친 유닉스와 유사한 쉘입니다. (말 그대로 ” 마지막으로 홈페이지의 90 년대 명령 줄 셸 “이라고 말합니다.) 필자는 최근 몇 년 동안 실제로 (주류) 테이블에 새로운 것을 가져다 준 것이 PowerShell인데, 안타깝게도 Windows에 너무 오래 국한되어 있고 여전히 .NET에 국한되어 있습니다. 예를 들어 아직 수행되지 않은 ‘ PowerShell에는 그다지 새로운 기능이 아직 없습니다. DCL 또는 JCL에서하지만 (다소) 세련된 방식으로 수행되었습니다.
- @bmike 왜 ksh를 사용하지 않습니까? Apple은 최신 버전을 제공합니다. 내 자신은 오래 전에 bash를 펀칭했으며 지금 zsh를 사용할 이유가 없습니다.
- 이 답변은 bash와 zsh의 차이점을 전혀 설명하지 않습니다. ‘ … 그리고 ‘ macOS 사용자의 95 %가 “을 지정하는 이유를 잘 모르겠습니다. ‘ 명령 줄 사용 안 함 “은 분명히 bash를 사용하는 사용자의 질문과 관련이 있습니다.
답변
내 셸 스크립트는 그렇게 복잡하지 않습니다.
셸 스크립트에 shebang 줄이 있습니까 (#! /bin/bash
또는 이와 유사한 것으로 시작)? 그렇지 않다면 실수로 bash를 사용하여 shebang없이 스크립트를 실행하는 bash 기능을 사용했을 수 있습니다. dash 또는 zsh와 같은 다른 셸은 OS에 맡기고 일반적으로 대신 /bin/sh
를 사용합니다. macOS의 /bin/sh
는 /bin/bash
의 복사본이며 아마도 남아있을 것입니다. 그러나 는 다른 동작을 갖도록합니다. 세부 사항은 Bash 매뉴얼, 6.11 Bash POSIX 모드 입니다. 몇 가지 요점 :
- Bash는
POSIXLY_CORRECT
변수가 설정되었는지 확인합니다.
이 환경 변수는 특히 GNU 도구가 설치된 경우 여러 다른 도구의 동작에 영향을 미칠 수 있습니다.
- 프로세스 대체를 사용할 수 없습니다.
프로세스 대체는 <(...)
또는 >(...)
구문입니다.
.
및source
내장 기능은 현재 디렉토리에서 파일 이름을 검색하지 않습니다. PATH를 검색하여 찾을 수없는 경우 인수입니다.
스크립트가 . foo
현재 디렉토리에서 foo
라는 파일을 가져올 것으로 예상하지만 작동하지 않습니다. 대신 . ./foo
를 수행해야합니다.
숫자에서 알 수 있듯이 POSIX 모드에서 bash의 동작에는 사소한 차이가 많이 있습니다. 스크립트에 bash를 사용하려는 경우 shebang을 사용하는 것이 가장 좋습니다.
Comments
- 내가 작성한 대부분의 쉘 스크립트처럼 보입니다. e 또는 shebang에서 명시 적으로 state / bin / bash를 사용하거나 (매우 적음) / bin / sh (거의 모두) 상태를 사용하여 적어도 문제가되지 않도록합니다. 감사합니다.
- 현재 프로세스 대체가 가능하다고 생각합니다. 나는 또한 Catalina에서 성공적으로 시도했습니다. 참조 : zsh.sourceforge.net/Intro/intro_7.html
- @Siu가 여전히 우승 ‘ shebang에서
/bin/sh
또는/bin/bash
를 사용하는 div> t 도움말 스크립트. Zsh는 기본 대화 형 셸일 뿐이며 ‘ 모든 곳에서 bash를 대체하지 않았습니다. - @muru 아, 이해합니다. 나는 대답을주의 깊게 읽지 않았고 저자가 프로세스 대체에 대해 이야기하고 있다고 생각했습니다.
zsh
😅
Answer
간단하게 유지한다는 정신으로 …
누구나 간단한 실용성을 제공 할 수 있습니까? Catalina가 출시 될 때 새로운 셸을 준비하기 위해 작업을 시작할 수 있도록하기 위해 알아야 할 특정 장애물 또는 특정 걸림돌이 있습니까?
If 새로운 기본 셸을 사용하려고 생각 중입니다.
- Zsh를 사용하여 컴퓨터의 셸 설정을 변경하지 않고 몇 가지 차이점을 느끼고 싶다면 Docker 컨테이너에있는 Powerline10k 를 시도해보고 차 한잔인지 확인하세요.
- 모든 종이 필요하지 않은 경우 휘파람을 불고 Bash를 기본 스크립트로 사용하는 것은 여기에서 다른 사람들이 설명한 것처럼 쉘을 설정하는 것이 다소 쉽습니다. Bash 5의 기능 을 사용하려는 것은 “상당히 macOS 용 사소한 업그레이드 입니다. li>
- 두 셸에서 예상대로 작동하도록 스크립트의 이식성을 개선하려면 POSIX 준수 여부를 테스트 “바 시즘”을 제거합니다. 저는이를 위해 ShellCheck 를 사용했으며 덜 복잡한 스크립트에서 매우 잘 작동합니다.
특정 경로는 명확하지 않지만 이 세 가지 접근 방식은 문제 또는 솔루션 공간을 과도하게 설계하지 않고도 정보에 입각 한 결정을 내릴 수있는 충분한 확신을 제공합니다.
bash version 3.2.57(1)
를 사용하는 경우 : Apple에서bash
시스템에서 ” 중요한 ” 무엇입니까?