在 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。不推荐使用反引号作为子 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

相关内容