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最初の関数変数に出力があります。

$FILES2番目の関数への入力として渡されます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]}

配列の詳細については、以下を確認してください。ここ

もう1つの方法は、名前を提供し、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

おすすめ記事