Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shell and exec commands #118

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

gportay
Copy link
Contributor

@gportay gportay commented Nov 29, 2023

Hello,

This PR adds two commands:

cqfd shell opens an interactive shell from within the container. It is compliant with the sh(1) as it runs $SHELL underneath. For example: cqfd shell -c "cat /etc/os-release" outputs the distribution release from the container. It is an alternative to cqfd run that is too restricted by running somehow /bin/sh -c with a list of arguments that is hard to operate with.

cqfd exec COMMAND [ARGUMENTS] runs the given command from within the container. Fox example: cqfd exec cat /etc/os-release outputs the distribution release from the container. It tries to address #99, cqfd exec git commit -m "A multiple word commit message not breaking command"

Ping me if it makes sense.

Regards,
Gaël

@gportay
Copy link
Contributor Author

gportay commented Nov 29, 2023

BTW, I do very often cqfd run bash to run commands from the container, to bypass the command= set in .cqfdrc.

cqfd Outdated
shell)
shift
config_load $flavor
command_string="${SHELL:-/bin/sh}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one could be tricky, as many users use fish/zsh/etc. on their host (and as a result $SHELL is normally set accordingly) but most container images don't include them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, we can have a CQFD_SHELL instead that default to /bin/sh and that can be overriden by .cqfdrc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or maybe cqfd bash, cqfd sh, cqfd zsh, cqfd fish... as in d9a715c.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, in the end, the cqfd bash is a short hand for cqfd exec bash 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or maybe cqfd bash, cqfd sh, cqfd zsh, cqfd fish... as in d9a715c.

TBH, I really like that idea! All it needs is to dress a list of the shells, then cqfd user can run cqfd whatever-funky-shell and it opens that whatever-funky-shell from the container.

The CQFD_SHELL environment is still used by cqfd shellso it run the shell specified by $CQFD_SHELL (and defaults to /bin/sh if unset).

What do you think?

This adds the shell command to run a $CQFD_SHELL (or /bin/sh) command
from within the container.

It is a convenient frontend to "cqfd run bash", which also respects the
arguments:

	$ cqfd shell -c 'printf "0=$0,*=$*,#=$#\n"' zero one two three
	0=zero,*=one two three,#=3

While the run command does not:

	$ cqfd run /bin/bash -c 'printf "0=$0,*=$*,#=$#\n"' zero one two three
	printf: usage: printf [-v var] format [arguments]

	$ cqfd run /bin/sh -c 'printf "0=$0,*=$*,#=$#\n"' zero one two three
	0=bash,*=,#=0\n: 1: printf: usage: printf format [arg ...]

Note: The command shell does not run the command= set in the file
.cqfdrc.
TL;DR; The command run takes arguments as if they are given to system()
(i.e. the command_string is intepreted by sh -c). The command shell
takes arguments as if they are given to execlp($SHELL, ...), and the new
command exec takes arguments as they are given to execlp() (i.e. for the
two last, the command is not interpreted by sh; except for the arguments
that are not simple-quoted and that are subject to get interpreted by
the current shell). In short:
 - cqfd run -> sh -c "$*"
 - cqfd shell -> sh "$@"
 - cqfd exec -> ssh "$@"

This adds the exec command to run a command from within the container.

The command consists of the exec-program and its arguments (if any), as
it is given to the C function execlp(). The exec-program could be either
a binary or a script.

	$ cqfd exec COMMAND [ARGUMENTS...]

It is a distinct CLI to the commands run and shell that both takes a
command_string as it is given to the C function system() (i.e. given to
sh -c):
 - cqfd shell has three different forms:
   cqfd shell [command_file [argument...]]
   cqfd shell -c command_string [command_name [argument...]]
   cqfd shell -s [argument...] (requires CQFD_EXTRA_RUN_ARGS=-i for now)
 - cqfd run [-c] [command_string] takes a command_string as specified by
   sh(1) or the command= attribute from the file .cqfdrc.
   Important: the option -c of run is for concatenate and it is
   different to the option -c of sh(1).

Note: The command exec (as the command shell) does not run the command=
set in the file .cqfdrc.

According to sh(1):

	argument

	The positional parameters ($1, $2, and so on) shall be set to
	arguments, if any.

	command_file

	The pathname of a file containing commands. If the pathname
	contains one or more <slash> characters, the implementation
	attempts to read that file; the file need not be executable. If
	the pathname does not contain a <slash> character:
	* The implementation shall attempt to read that file from the
	  current working directory; the file need not be executable.
	* If the file is not in the current working directory, the
	  implementation may perform a search for an executable file
	  using the value of PATH, as described in Section 2.9.1.1,
	  Command Search and Execution.

	Special parameter 0 (see Section 2.5.2, Special Parameters)
	shall be set to the value of command_file. If sh is called using
	a synopsis form that omits command_file, special parameter 0
	shall be set to the value of the first argument passed to sh
	from its parent (for example, argv[0] for a C program), which is
	normally a pathname used to execute the sh utility.

	command_name

	A string assigned to special parameter 0 when executing the
	commands in command_string. If command_name is not specified,
	special parameter 0 shall be set to the value of the first
	argument passed to sh from its parent (for example, argv[0] for
	a C program), which is normally a pathname used to execute the
	sh utility.

	command_string

	A string that shall be interpreted by the shell as one or more
	commands, as if the string were the argument to the system()
	function defined in the System Interfaces volume of
	POSIX.1‐2017. If the command_string operand is an empty string,
	sh shall exit with a zero exit status.

Fixes: savoirfairelinux#99
This are convenient short hands for:

	CQFD_SHELL=/bin/bash cqfd shell
@joufellasfl
Copy link
Contributor

Thanks, I merged the shell part, the rest will follow soon.

@gportay
Copy link
Contributor Author

gportay commented Feb 25, 2024

Thanks, I merged the shell part, the rest will follow soon.

Thank you very much! I guess cqfd deserves a new release soon as well :)

EDIT; The exec was introduced to address #99.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants