1

Problem

One of the configuration scripts from a package in my singularity container contains this perfectly reasonable (to me) bit of bash to trim a trailing / off a path;

if [ "${MY_DIR_PATH: -1}" = "/" ]; then
    MY_DIR_PATH="${MY_DIR_PATH%?}"
fi

It works fine natively on my machine, but when run from the %post section of a singularity container it fails with Bad substitution. What's going wrong and what is the correct workaround?

Minimal working example

Save the text below as badSubs.def then try; sudo singularity build badSubs.sif badSubs.def.

BootStrap: docker
From: ubuntu:18.04

# what is done when the container is built
%post
    # make print colour #
    GREEN='\033[0;32m'
    NOCOLOUR='\033[0m'
    # start
    #echo "${GREEN}~~~ Give the user permission and control ~~~ ${NOCOLOUR}"
    #umask 000

    echo "${GREEN}~~~ this should work fine! ~~~ ${NOCOLOUR}"
    MYSCRIPT=$SINGULAITY_ROOTFS/confuzzel
    touch $MYSCRIPT
    chmod u+x $MYSCRIPT
    echo '#! /bin/bash' >> $MYSCRIPT
    echo 'PATHY="/what/a/path/"' >> $MYSCRIPT
    echo 'if [ "${PATHY: -1}" = "/" ]; then ' >> $MYSCRIPT
    echo '    echo yay!' >> $MYSCRIPT
    echo '    PATHY="${PATHY%?}"' >> $MYSCRIPT
    echo 'fi' >> $MYSCRIPT
    echo 'echo $PATHY' >> $MYSCRIPT
    cat $MYSCRIPT
    ./confuzzel

# metadata
%labels
    Author ClumsyCat
    Version v1.0

%help
    to build me
    > sudo singularity build badSubs.sif badSubs.def
    to run me do
    > singularity run badSubs.sif


Clumsy cat
  • 289
  • 1
  • 12
  • run your script and look closely at the contents of your redirection to `$MYSCRIPT`. Does it had the correct quoting around `"${PATHY: -1}"` , etc? Good luck. – shellter May 30 '19 at 13:32

2 Answers2

2

I'm not familiar with singularity, so this is a guess, but I think your script is being run by a shell other than bash (maybe dash?). ${var: number} is a nonstandard extension to the variable expansion syntax; bash and a few other shells support it, others (like dash) don't.

If the only reason for the test is to find out if the variable ends in "/" so you can remove it if it's there, don't bother. This is POSIX-standard syntax that'll remove a "/" from the end of the variable if the variable ends in "/":

MY_DIR_PATH=${MY_DIR_PATH%/}

If you really do need to test, use this instead:

if [ "${MY_DIR_PATH%/}" != "${MY_DIR_PATH}" ]; then

Explanation: This compares the variable with "/" remove from the end to the original value; if they're different, there must've been a "/" at the end.

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
  • This is correct. Singularity uses /bin/sh during the `%post` process. The shebang in beginning _should_ be forcing bash though, so it's a little weird. You can add `ls -l /proc/$$/exe` to the script to see which shell is actually executing it. – tsnowlan May 31 '19 at 08:59
-1

OK, answering my own question because I found something that works;

if [ $(echo -n $MY_DIR_PATH | tail -c 1) = "/" ]; then
    MY_DIR_PATH="${MY_DIR_PATH%?}"
fi

Inspired by https://stackoverflow.com/a/32872687/7690011

If someone wanted to answer/add to this answer in a way that explained why this worked I would accept that answer.

Clumsy cat
  • 289
  • 1
  • 12