Linux

在bash腳本中將變數從一個函式傳遞到另一個函式

  • May 5, 2020

我是 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

輸出

請幫忙!在此處輸入圖像描述

這取決於您的案例如何將數據從一個功能傳輸到另一個功能。

我無法重現您的錯誤 - 也許它與aws或有關s3cmd。不推薦使用反引號作為子shell - 您應該使用$().

如果您只想傳遞數據並且對將它們儲存到硬碟驅動器不感興趣,則可以使用全域數組(您未聲明的所有內容都是全域的):

#!/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

引用自:https://unix.stackexchange.com/questions/584599