Linux
在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
輸出
這取決於您的案例如何將數據從一個功能傳輸到另一個功能。
我無法重現您的錯誤 - 也許它與
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