2

Hello I'm brand new to shell scripting, so sorry if this is trivial. How do you use printf command with the -v option?

In our deployment.sh file we have this line printf -v BITBUCKET_COMMIT_str %q "$BITBUCKET_COMMIT"

echo 'Initializing new deployment'
printf -v BITBUCKET_COMMIT_str %q "$BITBUCKET_COMMIT"
echo "commit string $BITBUCKET_COMMIT_str"

When the Bitbucket pipeline runs, it always fails at this line. With the error printf -v is an illegal option.

Error from Bitbucket


Initializing new deployment
commit string 
deployment.sh: 28: printf: Illegal option -v
bash: -c: line 1: syntax error: unexpected end of file
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! XXXXX deploy: `sh deployment.sh`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the XXXX deploy script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/XXX-debug.log

I've tested the printf -v command in a local terminal and it works fine, so I don't know why it doesn't work in the Bitbucket build pipeline. I've tried replacing printf with just a variable, but then I get a syntax error later on in the file. I think that's because we try to use the variable as in input for another command

"bash -s $BITBUCKET_COMMIT_str" <<\HERE
     echo "TEST MADE IT HERE"
     BUILD_FOLDER="BUILD_$BITBUCKET_COMMIT"
     echo "Build: $BUILD_FOLDER"
    ...
    HERE

On another note I'm not entirely sure what the above script is trying to do. I haven't been able to find what the bash -s command does. I think this command is trying to append a file with the contents of the HERE block. The script inside the HERE block doesn't seem to run unless I change << to >> The code inside the HERE block seems to run. But from what I understand about the << that change doesn't really make sense.

Any help would be greatly appreciated. Most of my team is on holiday so I'm having a tough time with this. Thanks in advance :)

adam.k
  • 131
  • 4
  • 1
    `printf -v` in general does not work - except for `ksh93` ans `bash`. Do yu use bash? – schily Jul 07 '20 at 14:52
  • @adam.k, so what's the error message you get, exactly? What's the line that uses `printf -v`, exactly? Is there really that dash in front of `-printf -v` like you show? How do you run the script? Also, what's that `printf -f` command you refer to? – ilkkachu Jul 07 '20 at 15:02
  • @ilkkachu `printf -f` and `-printf -v` were typos. I've fixed them in my question. The exact line that uses `printf -v` is what I posted. That is the only command on that line. The script runs when I push the code up to Bitbucket (I'm not sure how to do it locally, because the script uses Bitbucket variables). – adam.k Jul 08 '20 at 05:22
  • @schily The top of the script file is `#!/bin/sh` I've tried changing to `#!/bin/bash`, and I get the same . I'm not sure what we are actually using. I don't seem to have the access rights to look at deploy settings on Bitbucket :( – adam.k Jul 08 '20 at 05:25
  • Do you have `#! /bin/bash` at the top of your deployment script? How exactly does your BitBucket config run the deployment script? – muru Jul 08 '20 at 05:25
  • the `-v` option is a bash4+ feature iirc, which version of bash do you hve? – Jetchisel Jul 08 '20 at 05:29
  • 1
    @roaima The script runs in Bitbucket, meaning that it is executed. However, the script does not run successfully. The script throws an error, and fails the build process. – adam.k Jul 08 '20 at 05:49
  • Sorry, thank you. Yes I did miss that. – roaima Jul 08 '20 at 06:22
  • @Jetchisel, no, `printf -v` is in Bash 3.2 too. Also, Bash's error message is different. (which is one reason I asked for the exact error message -- it helps identify the shell that actually runs) – ilkkachu Jul 08 '20 at 08:36
  • @schily, my copy of ksh93 doesn't even support that :/ Zsh does, though. – ilkkachu Jul 08 '20 at 08:53
  • How exactly does your BitBucket config run the script? If it's doing `sh deployment.sh`, all the shebangs in the world won't help. – muru Jul 08 '20 at 08:54
  • @ilkkachu, yeah my bad twas the printing of time/date i was thinking about using the `-v` – Jetchisel Jul 08 '20 at 09:16
  • @ilkkachu You are right, I was mistaken. – schily Jul 08 '20 at 13:14

1 Answers1

2
printf -v BITBUCKET_COMMIT_str %q "$BITBUCKET_COMMIT"
echo "commit string $BITBUCKET_COMMIT_str"

deployment.sh: 28: printf: Illegal option -v

That looks like an error message from Dash, Debian's /bin/sh. This is the point where the question would be if the hashbang at the start of the script is correct, but you already mentioned that in the comments.

The workaround for -v would be using command substitution, var=$(printf whatever) but then you'd hit a problem with %q, since Dash doesn't support that either, and it's somewhat difficult to replace since the ${var/pattern/replacement} expansion is also not supported.

But look at the next line. You're using that variable BITBUCKET_COMMIT_str to print to the user. That doesn't necessarily require quoting valid for shell input, which is what %q does. (And %q doesn't even produce nice-looking output, it prioritizes using backslashes instead of just using single quotes.) So, if that's the only place you use the variable, and it doesn't contain e.g. newlines (if it's a commit id or such, it probably doesn't), you could probably just skip the printf altogether, and use something like this:

echo "commit string '$BITBUCKET_COMMIT'"

If you really need Bash's %q, and Bash is at all available, an obvious but very overkill solution is to call Bash to do it:

quotedvar=$(bash -c 'printf %q "$1"' bash "$var")
ilkkachu
  • 133,243
  • 15
  • 236
  • 397
  • Thanks for the suggestion. $BITBUCKET_COMMIT_str is used lower down in the file as well. The echo was there for my testing to see if something is actually being printed. I'll try the overkill option in that case. – adam.k Jul 08 '20 at 10:57
  • @adam.k, still, if it's not really used as input to shell as code (through `eval` or a manually started shell), you probably don't need the quoting. If it's just used a variable in the arguments of some cmd, then just `somecmd blah blah "$BITBUCKET_COMMIT"` should do – ilkkachu Jul 08 '20 at 11:01
  • OK thanks for your help. Overkill option works, as does just using a normal variable, at least for getting rid of the error. There is still a syntax issue somewhere else in the file, so I'll have to do more digging around that. – adam.k Jul 08 '20 at 11:50