Well I’m trying to create a script to automate the user creation in Linux servers, so I generated the ssh keys in each server and made a code like this:
user = teste p = 'senha123' os.system("ssh myuser@lab sudo useradd -p " + p + " -d "+ "/home/" + user+ " -m "+ " -c ""+ name+"" " + user)`
But, I’m getting the error:
Usage: useradd [options] LOGIN useradd -D useradd -D [options] Options: -b, --base-dir BASE_DIR base directory for the home directory of the new account -c, --comment COMMENT GECOS field of the new account -d, --home-dir HOME_DIR home directory of the new account -D, --defaults print or change default useradd configuration -e, --expiredate EXPIRE_DATE expiration date of the new account -f, --inactive INACTIVE password inactivity period of the new account -g, --gid GROUP name or ID of the primary group of the new account -G, --groups GROUPS list of supplementary groups of the new account -h, --help display this help message and exit -k, --skel SKEL_DIR use this alternative skeleton directory -K, --key KEY=VALUE override /etc/login.defs defaults -l, --no-log-init do not add the user to the lastlog and faillog databases -m, --create-home create the user's home directory -M, --no-create-home do not create the user's home directory -N, --no-user-group do not create a group with the same name as the user -o, --non-unique allow to create users with duplicate (non-unique) UID -p, --password PASSWORD encrypted password of the new account -r, --system create a system account -R, --root CHROOT_DIR directory to chroot into -s, --shell SHELL login shell of the new account -u, --uid UID user ID of the new account -U, --user-group create a group with the same name as the user -Z, --selinux-user SEUSER use a specific SEUSER for the SELinux user ma pping 512
When I remove ssh myuser@lab
part, the script work in the localhost.
Could someone help me with this issue?
Advertisement
Answer
You are treating ssh
as if it used execve(2)
semantics, where you pass commands and arguments as individual parameters (the way sudo
, xargs
, and find -exec
works).
ssh
instead uses system(3)
semantics, so it expects a single literal shell command (like su
, eval
, bash -c
and Python’s os.system
).
One general purpose way of doing this for arbitrary commands is to first assign the shell command you want to run to another string:
remote_command="sudo useradd -p " + p + " -d "+ "/home/" + user+ " -m "+ " -c ""+ name+"" " + user
And then use shlex.quote
to escape it for ssh
:
import shlex os.system("ssh myuser@lab " + shlex.quote(remote_command))
Alternatively, skip the system()
to avoid having to add another layer of escaping:
import subprocess subprocess.run(["ssh", "myuser@lab", remote_command], shell=False)