bash 스크립트에서 한 함수의 변수를 다른 함수로 전달

bash 스크립트에서 한 함수의 변수를 다른 함수로 전달

저는 Linux를 처음 사용하고 동일한 bash 스크립트에서 한 함수의 변수를 다른 함수로 전달하려고 합니다.

아래는 내 코드입니다.

#!/bin/bash -x

FILES=$(mktemp)
FILESIZE=$(mktemp)

command_to_get_files(){
 aws s3 ls "s3://path1/path2/"| awk '{print $2}'  >>"$FILES"
}

command_to_get_filesizes(){

for file in `cat $FILES`
 do
 if [ -n "$file" ]
  then
  # echo $file
   s3cmd du -r s3://path1/path2/$file | awk '{print $1}'>>"$FILESIZE"

 fi
 done
}

files=( $(command_to_get_files) )

filesizes=( $(command_to_get_filesizes) )

따라서 위 코드에서는 $FILES첫 번째 함수 변수에 출력이 있습니다.

$FILES두 번째 함수에 대한 입력으로 전달됨command_to_get_filesizes

하지만 다음과 같은 오류가 발생합니다 Broken Pipe.

누구든지 한 함수에서 다른 함수로 지역 변수를 전달하는 데 도움을 줄 수 있습니까?

$FILES의 출력은 다음과 같습니다.

2016_01
2016_02
2016_03
2016_04

산출 여기에 이미지 설명을 입력하세요. 도와주세요!

답변1

한 함수에서 다른 함수로 데이터를 전송하는 방법은 사용 사례에 따라 다릅니다.

aws귀하의 오류를 재현할 수 없습니다. 또는 관련이 있을 수 있습니다 s3cmd. 서브셸에 백틱을 사용하는 것은 더 이상 사용되지 않습니다. 를 사용해야 합니다 $().

단지 데이터를 전달하고 하드 드라이브에 저장하는 데 관심이 없다면 전역 배열을 사용할 수 있습니다(선언하지 않은 모든 것은 전역입니다).

#!/usr/bin/env bash

command_to_get_files() {
  local ifs
  # store the internal field separator in order to change it back once we used it in the for loop
  ifs=$IFS
    # change IFS in order to split only on newlines and not on spaces (this is to support filenames with spaces in them)
  IFS='
'
  # i dont know the output of this command but it should work with minor modifications
  # used for tests:
  # for i in *; do
  for file in $(aws s3 ls "s3://path1/path2/" | awk '{print $2}'); do
    # add $file as a new element to the end of the array
    files+=("${file}")
  done
  # restore IFS for the rest of the script to prevent possible issues at a later point in time
  IFS=${ifs}
}

# needs a non-empty files array
command_to_get_filesizes() {
  # check if the number of elements in the files-array is 0
  if (( 0 == ${#files[@]} )) then
    return 1
  fi
  local index
  # iterate over the indices of the files array
  for index in "${!files[@]}"; do
    # $(( )) converts the expression to an integer - so not found files are of size 0
    filesizes[${index}]=$(( $(s3cmd du -r "s3://path1/path2/${files[${index}]}" | awk '{print $1}') ))
    # used for testing:
    # filesizes[${index}]=$(( $(stat -c %s "${files[$i]}") ))
  done
}

command_to_get_files
command_to_get_filesizes

# loop over indices of array (in our case 0, 1, 2, ...)
for index in "${!files[@]}"; do
  echo "${files[${index}]}: ${filesizes[${index}]}"
done

Bash 배열에 대한 참고 사항:

  • 배열의 크기를 가져옵니다.${#array[@]}
  • 첫 번째 요소의 크기를 가져옵니다.${#array[0]}
  • 배열의 인덱스를 가져옵니다.${!array[@]}
  • 배열의 첫 번째 요소를 가져옵니다.${array[0]}

배열에 대한 자세한 내용은 다음을 확인하세요.여기.

또 다른 방법은 이름을 제공 echo하고 이를 다른 함수에 인수로 제공하는 것입니다(여러 단어로 구성된 파일 이름에는 어렵습니다).

임시 파일을 사용하면 다음과 같은 결과가 발생합니다.

#!/usr/bin/env bash

readonly FILES=$(mktemp)
readonly FILESIZES=$(mktemp)

# at script exit remove temporary files
trap cleanup EXIT
cleanup() {
  rm -f "$FILES" "$FILESIZES"
}

command_to_get_files() {
  aws s3 ls "s3://path1/path2/" | awk '{print $2}' >> "$FILES"
}

command_to_get_filesizes() {
  while read -r file; do
    s3cmd du -r "s3://path1/path2/${file}" | awk '{print $1}' >> "$FILESIZES"
  done < "$FILES"
}

command_to_get_files
command_to_get_filesizes

관련 정보