1

I'm trying to record the size of the compressed build file using Fastlane in my CICD pipeline. If I try this in the command line:

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

it works fine. However, if I try to put it in my script, like so:

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}"'
  '''

it gives me these syntax errors:

[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
    ^~~

I'm kind of a newbie to shell scripting, so any help is appreciated - I probably just have some quotes in the wrong place or something. If it helps, Fastlane uses Ruby syntax, so that's Ruby string interpolation in there.

Edit:

Here's the whole lane I'm calling in my fastfile, for more context:

# 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

I tried moving the filepath/filename out to its own variable, but I'm still getting the same issue.

10
  • 1
    Beware that du gives the 'size on disk' of the file - which may be either more or less than the 'size' of the file, depending on block size and sparse files and the like. If you want to know how many bytes long the file is, the most portable way is to use stat --format %s <filename>.
    – Popup
    Sep 6, 2023 at 14:19
  • 1
    @Kusalananda the lack of space is intentional - I don't want a space between the path to the file and the file name. The #{} is ruby string interpolation (I think - I'm not super familiar with ruby syntax either, so Fastlane may be doing its own thing here.)
    – KDBartleby
    Sep 6, 2023 at 14:30
  • 1
    shellcheck.net can help with syntax issues Sep 6, 2023 at 14:38
  • 1
    The error is from Fastfile, which I guess is some Ruby thing from the tags, so IMO this should be asked on Stack Overflow where someone with Ruby expertise can help with embedding the shell script in Ruby. Also: why do this processing in the shell script instead of getting the du output and processing that in Ruby directly to create your message?
    – muru
    Sep 6, 2023 at 14:41
  • 1
    Fully agreeing with Muru: As said in my first comment, the problem is with how you embed this in the rest of your code, not with the shell script itself. It's ruby complaining about the syntax, not your shell! Also, you're using ruby: why run a shell script to get the size of a file? I bet there's ruby built-in functionality that does things Sep 6, 2023 at 14:59

3 Answers 3

2

The bash idiom for catching the output from commands like:

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

and saving the output into a variable is:

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

This is very similar to a line you have in the Bash part of your script, except your code is missing the $ before the (. This seems likely to be a main cause for the confusing output you're getting.

1

It seems, you want to try a command substitution.

In your example you have

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

as an valid command substitution.

Your second command substitution fails because of the missing $. It's should look like

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

The available two command substitutions in bash are the modern POSIX style

$(command)

or the older style

`command`

It's recommended to use the first one, by the way it's increase readability.

If you want to make your code more readable, try to code like you speak. Another way to get the file size in a more readable way without a pipe and another command could be

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

In your example you could try

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

In Ruby you can use:

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .