如何在 shell 脚本中打印出文件大小?

如何在 shell 脚本中打印出文件大小?

我正在尝试在 CICD 管道中使用 Fastlane 记录压缩构建文件的大小。如果我在命令行中尝试这个:

du -h fileName.ipa | awk '{print $1}'

效果很好。但是,如果我尝试将其放入我的脚本中,如下所示:

sh '''
  # Add filesize to release message
  
  var fileName=`cat '"#{IPA_FILE_NAME_FILE}"'`
  fileSizeInfo=(du -h '"#{IPA_FILE_PATH}"'$fileName | awk '{print $1}')
  echo "$buildInfo"
  sed -i -e "s|FILESIZE_INFO|'"$fileSizeInfo"'|g" '"#{RELEASE_MESSAGE_HTML_FILE_NAME}"'
  '''

它给了我这些语法错误:

[17:50:24]:     262:          var fileName=`cat '"#{IPA_FILE_NAME_FILE}"'`
[17:50:24]:  => 263:          fileSizeInfo=(du -h '"#{IPA_FILE_PATH}"'$fileName | awk '{print $1}')
[17:50:24]:     264:          echo "$buildInfo"
[17:50:24]:     265:          sed -i -e "s|FILESIZE_INFO|'"$fileSizeInfo"'|g" '"#{RELEASE_MESSAGE_HTML_FILE_NAME}"'
[!] Syntax error in your Fastfile on line 263: Fastfile:263: syntax error, unexpected '{', expecting `end'
..._FILE_PATH}"'$fileName | awk '{print $1}')
...                              ^
Fastfile:285: syntax error, unexpected `end', expecting end-of-input
    end
    ^~~

我是 shell 脚本的新手,所以任何帮助都是值得赞赏的 - 我可能只是在错误的位置或其他地方引用了一些内容。如果有帮助的话,Fastlane 使用 Ruby 语法,所以里面有 Ruby 字符串插值。

编辑:

这是我在快速文件中调用的整个通道,以获取更多上下文:

# Send message MS Teams Channel
    lane:sendTeamsMessage do |options|
=begin
  MS Teams messages are sent using webhooks and it got limited support to HTML and Markdown. 
  This implementation uses HTML formatted message.
  Webhook will not accept new lines or double quotes because it can break the JSON struture.
  The message file preparation is done in multiple steps.
  1. Add .ipa file size info to release message HTML
  2. Replace all double quotes with single quotes  
  3. Copy the Teams message payload template and update it with the message content
  4. Replace 'MESSAGE_INFO' string with the HTML formatted content file
  5. Send the message to Teams channel
=end
      sh '''
      # Add filesize to release message
      
      var fileName=`cat '"#{IPA_FILE_NAME_FILE}"'`
      var fullFilePath='"#{IPA_FILE_PATH}"'$fileName
      echo fullFilePath
      fileSizeInfo=(du -h $fullFilePath | awk '{print $1}')
      echo "$buildInfo"
      sed -i -e "s|FILESIZE_INFO|'"$fileSizeInfo"'|g" '"#{RELEASE_MESSAGE_HTML_FILE_NAME}"'
      '''

      sh '''
      # Copy the release message html file
      cp -fr '"#{RELEASE_MESSAGE_HTML_FILE_NAME}"' '"#{TEAMS_MESSAGE_FILE_NAME}"'
      '''
      # Replace all double quotes with single quotes to make it JSON friendly
      sh("sed","-i","-e","s|\"|\'|g","#{TEAMS_MESSAGE_FILE_NAME}")

      sh'''
      cp -fr '"#{TEAMS_PAYLOAD_TEMPLATE_FILE_NAME}"' '"#{TEAMS_PAYLOAD_FILE_NAME}"'
      message=`cat '"#{TEAMS_MESSAGE_FILE_NAME}"'`
      sed -i -e "s|MESSAGE_INFO|'"$message"'|g" '"#{TEAMS_PAYLOAD_FILE_NAME}"'
      '''
      # Send the message to Teams channel
      sh '''
      echo '"#{options[:webhook]}"'
      curl -H "Content-Type: application/json" -d @'"#{TEAMS_PAYLOAD_FILE_NAME}"' '"#{options[:webhook]}"'
      '''
    end

我尝试将文件路径/文件名移至其自己的变量中,但仍然遇到相同的问题。

答案1

bash捕获命令输出的习惯用法如下:

du -h fileName.ipa | awk '{print $1}'

将输出保存到变量中是:

fileSizeInfo=$(du -h fileName.ipa | awk '{print $1}')

这与脚本的 Bash 部分中的一行非常相似,只是您的代码$缺少(.这似乎可能是导致您得到的令人困惑的输出的主要原因。

答案2

看来你想尝试一下命令替换

在你的例子中你有

var fileName=`cat '"#{IPA_FILE_NAME_FILE}"'`

作为有效的命令替换。

您的第二个命令替换由于缺少$.它应该看起来像

fileSizeInfo=$(du -h $fullFilePath | awk '{print $1}')

可用的两个命令替换bash是现代的POSIX风格

$(command)

或较旧的风格

`command`

建议使用第一个,这样可以增加可读性。

如果您想让代码更具可读性,请尝试像您所说的那样编写代码。在没有管道和另一个命令的情况下以更可读的方式获取文件大小的另一种方法可能是

stat -c "%s" /path/to/file

在你的例子中你可以尝试

fileSizeInfo=$(stat -c "%s" $fullFilePath)

答案3

在 Ruby 中你可以使用:

File.stat("/path/to/file").size

相关内容