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.