I wrote a script that convert a icns file to png and then encode the png with base64.

I could do it in 2 steps:

  • sips -s format png test.icns -o test.png
  • base64 -w0 test.png

But since test.png is just an intermediary file, I'd like to pipe the output of the 1st command directly to base64, how do I do that?

Note that sips doesn't seem to support /dev/stdout as the argument of -o.

  • 2
    ffmpeg -i '/private/var/root/Desktop/Volume limiter.app/Contents/Resources/applet.icns' -c:v png -f rawvideo - | base64 – Joy Jin Nov 22 at 8:24
  • 1
    Using zsh: (){ sips -s format png test.icns --out $1; base64 $1 } =() – robertklep Nov 22 at 18:32
  • @robertklep does =() at the end invoke the function just defined? Where can I find more info about =()? Thanks! – Teddy C Nov 23 at 6:16
  • 1
    @TeddyC =(command) will return the name of a temporary file that contains the output of command. However, it also works without a command, and will create (and return the name of) an empty temp file. That filename is then passed to the function defined by () { … } as its first argument ($1). It's documented in the zshexpn manpage. – robertklep Nov 23 at 6:19
  • 1
    @robertklep this zsh trick is absolutely amazing! It is going to save me so much work. Thank you! – Teddy C Nov 23 at 13:43

The sips utility does not support outputting to stdout unfortunately, so you cannot directly pipe the resulting file into another program. And as you have already tested, it also does not support using /dev/stdout or a named pipe or similar, as it will recreate the file when outputting.

However, you can use ordinary shell scripting "tricks" to make a "one-liner" for combining the commands if you wish to do so:

 sips -s format png test.icns -o __$$ && base64 __$$ && rm __$$

Note that this is for Bash, and that it will create and delete a temporary file named __.

Also note that I have removed the -w0 parameter in your question from the base64 command. That is a parameter you would use on for example the Linux version of the base64 command, but the macOS command does not have such a parameter. Indeed that wrapping behaviour you request with that parameter is already on by default on macOS.

| improve this answer | |
  • I installed coreutils with brew and linked gbase64 to a dir in the $PATH before /usr/bin and removed the leading g. :) – Teddy C Nov 22 at 10:32
  • Does the oneliner produce a file with the name __$$ and then remove it? – Teddy C Nov 22 at 10:34
  • 1
    No, the file is named a number that changes with the process id - i.e. prevents a conflict if you have multiple Tabs and run the line multiple times. – jksoegaard Nov 22 at 11:54

You must log in to answer this question.

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