고쳐 쓰다 이것 좀 봐봐협회, 0 대신 1로 시작하도록 배열 첨자를 업데이트했는데 배열 변수가 올바르게 읽혀진 것 같습니다.
#!/bin/bash
#Root folders for Git update.
ROOT[1]="/Users/ayusman/dev/repos1"
ROOT[2]="/Users/ayusman/dev/repos2"
#do some things with the ROOT variable.
그런데 앞서 선언한 쉘 함수가 인식되지 않아서 다른 곳에서 오류가 보이기 시작했습니다.
명령을 찾을 수 없습니다: git
그래서 일반적인 질문은 다음과 같습니다.
bash 쉘에서 완벽하게 작동하는 쉘 스크립트를 zsh 쉘로 이식하려면 어떻게 해야 합니까?
최근에 Mac을 macOS Catalina 10.15.2로 업그레이드했습니다.
내 쉘 스크립트 중 하나는 다음과 같습니다.
#!/bin/bash
#Root folders for Git update.
ROOT[0]="/Users/ayusman/dev/repos1"
ROOT[1]="/Users/ayusman/dev/repos2"
#do some things with the ROOT variable.
내 기본 쉘이 bash 쉘이었을 때 이것은 잘 작동했습니다. 여기서 내가 한 일은 쉘 스크립트에서 사용할 배열 변수에 일부 폴더를 추가하는 것입니다. 업그레이드를 릴리스하고 기본 셸을 zsh로 설정한 후 스크립트를 시작할 때(.zsrc 파일의 별칭을 통해) 다음 오류가 발생합니다.
[ayusman@~10:39AM]$updateExpediaGitRepos
/Users/ayusman/scripts/updateGitRepos.sh:250: ROOT: assignment to invalid subscript range
[ayusman@~10:39AM]$
쉘을 다시 bash로 변경할 때(아래 표시된 대로 chsh를 실행하여) 동일한 스크립트가 예상대로 실행되는지 확인했습니다.
chsh -s /bin/bash
따라서 본질적으로 질문은 기존 bash 스크립트를 사용하지 않고 zsh 쉘에서 실행할 수 있습니까?
고마워요, 아유슈만
답변1
zsh
스크립트에 대한 설명을 요청하는 것 같습니다 . 당신은 updateExpediaGitRepos
그것이 무엇인지 말하지 않았지만 나는 생각했습니다.alias
원천이 스크립트는 .
또는 source
내장 명령을 사용합니다. 이 명령은 현재 쉘 해석기에 파일의 코드를 해석하도록 지시하므로 shebang( #! /bin/bash
)은 관련이 없습니다. Shebang은 시도하는 경우에만 커널에서 사용됩니다.구현하다스크립트.
아마도 이는 updateGitRepos.sh
사용자 쉘의 속성(예: 환경 변수 설정, 함수 정의, 별칭 정의 등)을 수정하여 사용자 환경을 사용자 정의하는 데 사용되며, 이 경우 실행하는 데 도움이 되지 않습니다.
bash
두 가지 서로 다르고 호환되지 않는 언어에 대한 통역사 입니다 zsh
(둘 다 Bourne 쉘, Korn 쉘 및 C 쉘에서 많은 영감을 얻기 때문에 공통점이 있지만). 일반적으로 한 사람이 다른 사람을 위해 작성된 코드를 해석할 수 있을 것이라고 기대할 수는 없습니다.
특히 배열은 매우 다르게 구현됩니다.
zsh
배열은 실제로 셸에서 일반적으로 사용되는 대부분의 다른 셸 및 도구와 마찬가지로 인덱스가 1에서 시작하는 배열입니다(자세한 내용은 다음을 참조하세요).Zsh 배열의 첫 번째 요소에 인덱스가 0이 아닌 1인 이유가 있나요?).
bash
배열은 Korn 쉘에서 복사됩니다. 이는 희소 배열(양의 정수로 제한된 키를 갖는 연관 배열과 유사)이며 인덱스는 0에서 시작합니다.
zsh
여러 지원시뮬레이션다른 쉘용으로 작성된 코드를 해석하는 데 사용할 수 있습니다. 특히 bash
배열을 사용하여 스크립트를 구문 분석하는 데 유용한 ksh 에뮬레이션 모드가 있습니다.
emulate ksh
시작하세요.
또는:
emulate ksh -c 'some code'
이 시뮬레이션 모드에서 코드를 평가합니다. 이 모드에서 선언된 함수는 시뮬레이션 모드를 상속합니다.
또한 ksh
시뮬레이션 모드에서는 이 KSH_ARRAYS
옵션이 켜져 있어 배열 인덱스가 0부터 시작됩니다(그러나 여전히 희박하지는 않음).
따라서 여기에서 별칭을 수정하여 다음과 같이 시도해 볼 수 있습니다.
emulate ksh -c '. /Users/ayusman/scripts/updateGitRepos.sh'
바꾸다
. /Users/ayusman/scripts/updateGitRepos.sh
귀하의 경우에는 이것으로 충분할 수도 있고 충분하지 않을 수도 있습니다. 이 시뮬레이션 모드만개선하다호환성을 위해 ksh
zsh를 ksh 복제본으로 만들지 않습니다. 그리고 ksh는 bash가 아닙니다.
사용자의 셸을 소스로 사용 하려면 updateGitRepos.sh
지원되는 각 셸에 대해 각각 적절한 언어로 작성된 다른 버전의 스크립트를 제공하거나 지원되는 모든 셸과 호환되는 구문을 사용해야 합니다. 일반적으로 배열은 제외됩니다. (그러나 참조어레이에 대한 테스트 셸 지원가능한 방법).
스크립트가 사용자의 대화형 셸에 의해 해석되지 않고 단순히 실행되는 경우 /path/to/the/script
shebang 덕분에 스크립트를 실행하면 올바른 해석기가 시작되어 해석할 수 있습니다. not , not source /path/to/the/script
( zsh /path/to/the/script
bash /path/to/the/script
여기에서도 다음과 같이 작동합니다. 이는 bash
스크립트입니다(오해의 소지가 있는 .sh
확장에도 불구하고)).
답변2
이 동작은 zsh
셸에서 배열이 작동하는 방식으로 인해 발생하며 해당 배열의 인덱싱은 1
및아니요존재하다 0
. 따라서 인덱스의 요소에 액세스하면 0
현재 보고 있는 오류가 발생합니다.
zsh
매뉴얼 에서 -15.2.1 배열 첨자
15.2.1 Array Subscripts
아래 첨자를 사용하여 배열의 개별 요소를 선택할 수 있습니다. 양식의 첨자는
[exp]
단일 요소를 선택합니다exp
. 여기서exp
는 마치 둘러싸인 것처럼 산술적으로 확장됩니다$((...))
. 요소 번호는 다음으로 시작합니다.1,KSH_ARRAYS
이 옵션이 설정되지 않은 경우 0부터 번호가 매겨집니다.이 옵션이 설정되지 않은 경우
KSH_ARRAYS
기본값은 아래 첨자를 사용하여 배열 요소에 액세스하는 것입니다.0으로 평가하고 빈 문자열을 반환합니다., 하지만이러한 요소에 쓰려는 시도는 오류로 처리됩니다.. 이전 버전과의 호환성을 위해KSH_ZERO_SUBSCRIPT
아래 첨자 값 0과 1이 동일하도록 이 옵션을 설정할 수 있습니다. 옵션 설명의 옵션 설명을 참조하세요.
따라서 index 로 시작하는 배열의 동작을 시뮬레이션하려면 0
스크립트 상단에서 이 옵션을 설정하세요.
setopt ksh_arrays
zsh
she-bang 인터프리터가 로 설정되어 있어도 스크립트가 동작을 나타내는 이유를 명확히 하기 위해 #!/bin/bash
스크립트는 명시적 호출로 실행될 수 있으며, zsh <script>
이 경우 운영 체제는 스크립트 상단의 인터프리터 줄을 인식하지 못합니다. 스크립트 자체가 실행 가능( chmod +x
)되고 를 사용하여 실행되면 ./<script>
스크립트 상단에 제공된 인터프리터가 적용됩니다.