Home > Software engineering >  Run bash commands inside container with alias
Run bash commands inside container with alias

Time:07-22

We have docker contianers, and i would like to run a bash command inside my container, through a script. Like so:

bin/run-in-container ls -la

where the script run-in-container looks something like this:

#!/usr/bin/env bash

docker compose exec container_name bash -ic "$@"

I cannot get my script to interpret all parameters, inside single quotes.

this interprets to docker compose exec api bash -ic ls -la
but what I want to to interpret is docker compose exec api bash -ic 'ls -la'

If i try to concatenate a string of single quotes and my parameters, it renders the character escaped:

#!/usr/bin/env bash

escaped_single_qoute="'"
docker compose exec container_name bash -ic $escaped_single_qoute "$@" $escaped_single_qoute

But this interprets into :

docker compose exec api bash -ic ''\''ls' '-la'\'''

Here is a MCVE: gist with Dockerfile and code

services:
  node:
    restart: unless-stopped
    image: 888aaen/bash_stackoverflow:latest 

    volumes:
      # Mount .bash_aliases file.
      - "./.bash_aliases:/home/node/.bash_aliases"

script

#!/usr/bin/env bash

docker compose exec node bash -ic "$@"

UPDATE: not solved

KamilCuk came with a great solution, but this does not run with aliases inside the contianer.

docker compose exec container_name bash -ic '"$@"' _ "$@"
# usage example: ./script ls -la
# usage example: ./script sh -c "ls -la ; echo another command"

Let's say we have these aliases:

# ~/.bash_aliases
alias ll='ls -l'
alias la='ls -la'

I want to be able to run

bin/run-in-container ll
which is possible with docker compose exec api bash -ic 'la src/'
but not with bin/run-in-container la src/

CodePudding user response:

If you want to pass a single command, just pass the command:

docker compose exec container_name "$@"
# usage example: ./script ls -la
# usage example: ./script sh -c "ls -la ; echo another command"

If you want to pass a single command with an (odd?) requirement in running the command inside bash interactive shell, you would forward the arguments and execute them inside the shell:

docker compose exec container_name bash -ic '"$@"' _ "$@"
# usage example: ./script ls -la
# usage example: ./script sh -c "ls -la ; echo another command"

If you want to pass a shell script, just like to eval, just concatenate arguments with space:

docker compose exec container_name bash -ic "$*"
# usage example: ./script ls -la
# usage example: ./script ls -la ';' echo another command
# usage example: ./script "$(printf "%q " sh -c "ls -la ; echo another command")"

Let's say we have these aliases:

That's all unorthodox. Aliases are for interactive shells, the 1000 years old advice is to use functions instead of aliases. .bash_aliases is a nonstandard (but common) file, that is not being sourced on bash startup unless explicitly mentioned in .bashrc file for interactive non-login shell. See https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html .

If your intention is to provide ll command for non-interactive use, instead create an executable in /usr/local/bin named ll that will call ls -l "$@" in it.

Another common convention, is to put functions (not aliases! aliases are for interactive shells) inside /etc/profile.d and then run an login non-interactive shell. People are used to doing sh -l when needing environment over ssh, the convention is somewhat understood by users.

  • Related