디렉터리 이름을 함수에 전달하려고 할 때 "디렉토리입니다" 오류가 발생합니다.

디렉터리 이름을 함수에 전달하려고 할 때 "디렉토리입니다" 오류가 발생합니다.

내 Bash 스크립트에서는 find를 사용하여 와일드카드로 폴더 이름을 가져옵니다.

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard});
do
  stuff=doStuff ${i}
done

doStuff() {
  echo ${1}
  return ${1}'/hello';
}

문제는 이 작업을 수행할 때 다음 오류가 발생한다는 것입니다(${i}가 "home/me/my_directory"에 해당한다고 가정).

line 111: '/home/me/my_directory': is a directory. 

(라인 111은 "doStuff"가 있는 라인입니다)

나는 이것을 시도했지만 소용이 없었습니다.

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard});
do
  stuff=doStuff "${i}"
done

분명히 이것은 프로그램이 디렉토리를 실행하려고 하기 때문이지만 나는 그것을 조작할 수 있는 문자열로 원합니다.

답변1

따옴표와 명령 대체가 문제입니다.

당신이 겪고 있는 구체적인 문제는 쉘이 /home/me/my_directory환경 변수를 사용하여 호출된 명령을 실행하려고 하기 때문입니다 stuff=doStuff.
당신이 정말로 원하는 것은 (제가 올바르게 해석한다면) doStuff의 값을 $i인수로 사용하여 실행하고 출력을 변수에 할당하는 것 입니다 stuff. 이를 수행하는 방법은 명령을 $().

stuff="$(doStuff "$i")"

내가 모든 것에 따옴표를 어떻게 넣었는지 주목하세요. 이는 쉘이 토큰화하기를 원하지 않는 것을 토큰화하는 것을 방지하기 위한 것입니다( /foo/bar baz단일 인수를 /foo/barand 로 바꿉니다 baz).

또한 함수의 출력은 return.

더 많은 따옴표를 사용해야 하므로 다른 모든 항목에도 추가해야 합니다. 다음은 스크립트의 전체 버전입니다.

doStuff() {
  echo "${1}" >&2
  printf '%s/hello' "$1";
}

IFS=$'\n'
for i in $(find "${directory}" -mindepth 1 -type d -name "${wildcard}");
do
  stuff="$(doStuff "${i}")"
done

함수 정의를 사용하기 전에 먼저 넣어야 합니다. 쉘은 파일을 여러 번 통과하는 컴파일된 프로그램처럼 구문 분석하지 않습니다. 이것은 하향식입니다. 또한 STDERR로 보내도록
수정했으며 터미널에 표시한 다음 STDOUT으로 보내고 변수에 캡처합니다 .doStuffechoprintfstuff

디렉토리에 개행 문자가 포함되어 있으면 여전히 문제가 발생할 수 있습니다. 그러나 이는 쉘의 한계입니다. 파일 경로에 포함될 수 없는 유일한 문자는 NULL 문자( \0)입니다. 그러나 bash 및 기타 쉘은 문자열에 NULL 문자를 저장할 수 없으므로(모두는 아니지만 다수. zsh는 가능하다는 것을 알고 있음) 구분 기호로 사용할 수 없습니다.

답변2

좋은 노력이지만 bash실제로는 간단한 스크립팅 언어인데도 프로그래밍 언어처럼 작성하려고 한다는 것을 보여줍니다. 당신의 구조의 문제 는 그것이 당신이 생각하는 것을 의미하지 않는다는 stuff=doStuff arg것입니다 . bashTo 는 bash변수 stuff=doStuff할당이자 arg명령입니다. 다음 두 링크를 읽어 보시기 바랍니다.

당신이 가지고있는 것과 유사한 작동 버전은 다음과 같습니다

doStuff () {
    echo "$1/hello"
}

stuff=$(doStuff "$i")

답변3

오류가 발생한 줄은 생각한 대로 작동하지 않습니다.

먼저 환경 변수 stuff를 "doStuff" 문자열로 설정한 다음 ${i}를 명령으로 실행하려고 시도합니다. ${i}는 디렉토리이기 때문에 주어진 오류 메시지와 함께 실패합니다.

관련 정보