다음 쉘 스크립트가 있습니다
#!/bin/bash
# Search elixir code with ack
# By default skip the dependencies and test directories
ignore_dirs=("dependencies" "test" "config")
# the for call below inserts newlines so we need to strip them out which is why the tr -d part is on the end
# of the assignment
ign_dirs="$(for i in "${ignore_dirs[@]}"; do echo "--ignore-dir=$i "; done | tr -d '\n')"
# By default skip the mix.exs file
ignore_files=("is:mix.exs" "is:credo.exs")
ign_files="$(for i in "${ignore_files[@]}"; do echo "--ignore-file=$i "; done | tr -d '\n')"
pager=less
file_types=elixir:ext:ex,exs,eex,heex
#echo ack $1 --word-regexp --pager="$pager" --type-set="$file_types" "$ign_dirs" "$ign_files" --noenv
# Array variation
ack $1 --word-regexp --pager="$pager" --type-set="$file_types" "$ign_dirs" "$ign_files" --noenv
# Hardcoded variation
ack $1 --word-regexp --pager=less --type-set=elixir:ext:ex,exs,eex,heex --ignore-dir=dependencies --ignore-dir=test --ignore-dir=config --ignore-file=is:mix.exs --ignore-file=is:credo.exs --noenv
주석 처리된 에코 라인을 사용하여 하드코딩된 변형을 만들었습니다. 하드코딩된 변형을 실행하면 ack가 예상대로 작동합니다. 배열 변형을 실행하면 ack가 명령줄 옵션을 볼 수 없는 것 같습니다. 예를 들어, 포함되어서는 안 되는 mix.exs를 포함하고 테스트 디렉터리를 검색합니다.
내 쉘 스크립트가 잘못 되었나요? 대부분의 쉘 스크립트를 복사/붙여넣었습니다. echo $ign_dirs
올바른 값을 볼 수 있고 볼 수 있다는 뜻입니다. 명령(배열 변형)을 실행할 때 작동하지 않습니다. 이는 내 쉘 스크립트에 아무런 문제가 없음을 나타내는 것 같습니다.
그런데 저는 이것을 Mac의 zsh에서 실행하고 있습니다. 나는 이것을 bash에서 테스트했고 같은 문제를 보았습니다.
이것이 어딘가에 있는 일종의 확인 FAQ라면 미리 사과드립니다. 확인했지만 문제를 해결하는 항목을 찾지 못했습니다.
편집하다:
나는 그것을 명확하게 말하지 않았다는 것을 알 수 있습니다.
결국 나는 Elixir 코드를 자동으로 검색하기 위해 ack를 사용하려고 했습니다. bash 스크립트 내에서 옵션/검색을 가능한 한 많이 유지하고 싶습니다. 그러면 다른 컴퓨터의 .ackrc 파일 및 환경 변수 변경에 대해 걱정할 필요가 없습니다.
내가 기대하는 것은 ack가 파일을 검색할 때 내가ignore_dirs에 나열한 디렉터리를 제외하고 Ignore_files에 지정한 파일을 건너뛰는 것입니다. 하드코딩된 변형을 사용하여 쉘 스크립트를 실행하면 디렉토리가 무시됩니다. 배열 변형을 사용하여 쉘 스크립트를 실행할 때 무시되지 않습니다.
예, ign_dirs와 ign_files는 배열이 아니라 문자열이라는 것을 알고 있습니다. 쉘 스크립트의 명령줄에서 직접 배열을 사용할 수 있습니까?
답변1
옵션에 대한 배열을 만듭니다 --ignore-*
.
ignore_dirs=("dependencies" "test" "config")
ign_dirs=()
for i in "${ignore_dirs[@]}"; do
ign_dirs+=("--ignore-dir=$i");
done
ignore_files=("is:mix.exs" "is:credo.exs")
ign_files=()
for i in "${ignore_files[@]}"; do
ign_files+=("--ignore-file=$i");
done
그런 다음 명령에서 다음 배열을 사용합니다.
ack "$1" --word-regexp --pager="$pager" --type-set="$file_types" "${ign_dirs[@]}" "${ign_files[@]}" --noenv
답변2
최종 명령에서 변수 주위의 따옴표를 제거합니다.
ack $1 --word-regexp --pager="$pager" --type-set="$file_types" $ign_dirs $ign_files --noenv
이러한 변수에는 공백으로 구분된 여러 부분이 있으며 공백으로 구분되기를 원합니다.
원본 코드(따옴표 포함)는 다음과 같이 확장됩니다.
ack $1 --word-regexp --pager=less --type-set=elixir:ext:ex,exs,eex,heex "--ignore-dir=dependencies --ignore-dir=test --ignore-dir=config" "--ignore-file=is:mix.exs --ignore-file=is:credo.exs" --noenv
따라서 값이 포함된 키 세트 대신 두 개의 위치 매개변수가 사용됩니다.