저는 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