bash script to perform action in a singularity con

2019-07-31 09:02发布

I am using the following workflow on RedHat in terminal:

  • open a singularity image:

singularity run /mn/sarpanitu/singularity/test/fenics-and-more.img

  • export some display inside the singularity:

export DISPLAY=:0.0

  • export a path to gmsh inside the singularity:

export PATH="$HOME/Downloads/gmsh-git-Linux64/bin:$PATH"

I want to put everything as a bash script. My first (not working) approach is the following (all in a singularity_script.sh file):

#!/bin/bash

function singularity_script(){
  singularity run /mn/sarpanitu/singularity/test/fenics-and-more.img
  export DISPLAY=:0.0
  export PATH="$HOME/Downloads/gmsh-git-Linux64/bin:$PATH"
}

I execute it by sourcing and then calling the function:

chmod +x singularity_script.sh
. singularity_script.sh
singularity_script

But of course, this does not work as the exports are done (I think?) in the parent terminal and not the son singularity. So I do not get the display and path exported correctly in singularity.

Any way to fix this? I guess the solution would be to automatically run the script inside the container at startup of the container, but how to do this simply?

2条回答
爷、活的狠高调
2楼-- · 2019-07-31 09:38

Got it! The solution by @tormodlandet had one problem, i.e. the singularity container died once the command called with the -c option were run.

I can get it to work by executing the following instead:

singularity shell /mn/sarpanitu/singularity/test/fenics-and-more.img -c "export DISPLAY=:0.0 && export PATH="$HOME/Downloads/gmsh-git-Linux64/bin:$PATH" && /bin/bash -norc"

This does the command I want in the singularity, and then spawns a gnome-terminal from within the singularity container that does not die until it is exited.

Missing the /bin/bash -norc at the end means that the singularity container dies after the last command.

So in order to call the useful commands from a script rather than the plain command, simply use:

singularity shell /mn/sarpanitu/singularity/test/fenics-and-more.img -c "bash script_singularity.sh && /bin/bash -norc"

where there is in the current working directory a script_singularity.sh file containing the commands to run:

echo "Hi there..."
export DISPLAY=:0.0
export PATH="$HOME/Download/gmsh-git-Linux64/bin:$PATH"
echo "...done exports!"

Edit

If you want to still have a good looking terminal, you can provide a bashrc config file. For example:

singularity shell /mn/sarpanitu/singularity/test/fenics-and-more.img -c "bash script_singularity.sh && /bin/bash -rcfile singularity_bashrc"

where singularity_bashrcis your bashrc to use. For example, it works great with (this is verbose to add here and there are many places with much more detailed bashrc explanations, but this was requested in some comments):

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
    # We have color support; assume it's compliant with Ecma-48
    # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
    # a case would tend to support setf rather than setaf.)
    color_prompt=yes
    else
    color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="sing-\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi
查看更多
Fickle 薄情
3楼-- · 2019-07-31 09:45

If you have access to change the Singularity image (or rebuild it), you can change the runscript. Otherwise you could put your bash script at a location that is mounted inside the Singularity image (probably the current working directory at least depending on your setup). Then run something like this (using exec)

singularity exec my_sing.img bash /pth/to/script.sh
查看更多
登录 后发表回答