I am using a python script to restrict the commands usage using the command argument in the authorized_keys file.
command:
ssh host-name bash --login -c 'exec $0 "$#"' mkdir -p hello
My script is performing required actions to restrict the commands. After filtering, the python script does sys.exit(1) for error and sys.exit(0) for success. After the return value the above ssh command is not getting executed at the end. Is there something else I need to send from the python script to SSH daemon?
The command modifier in the authorized_keys is not (only) used to validate the users command, but that command is run instead of the command provided by the user. This means calling sys.exit(0) from there prevents running the user-provided command.
In that script, after you validate the command, you need to run it too!
I think changing it to
ssh host-name bash --login -c 'exec $0 "$#" && mkdir -p hello'
should do the trick, otherwise bash will assume only the part in the single quotes is the command to execute.
If the second part should be executed even if the first part fails, replace the && with ;
Related
when I run "docker exec -it docker-name bash" on centOS7 service ,it will go into docker container and can run " python xx.py config.yaml " to execute some works .
but if I use Jenkins shell run "docker exec -it docker-name bash" ,it will have no response ,I write "python xx.py config.yaml " behind ,Jenkins show [ python: can't open file 'xxx.py': [Errno 2] No such file or directory ] ,I think this error is not into the docker container ,so can't find the python file that in the docker container .How can I enter the docker container with Jenkins shell .
When you run docker exec -it docker-name bash, you get an interactive shell inside the container that gets connected to your console and the next command you type to the console is executed in that shell.
But Jenkins has no console. It is executing a script, with the standard input connected to a null device (which always returns end of file on read). So in effect it is executing the equivalent of
docker exec -it docker-name bash </dev/null (the /dev/null is the null device and < connects it to standard input of the command). And if you do that on your console, nothing happens and you'll get your original prompt again.
But you don't have to, and shouldn't be, running bash in this case at all. You give docker exec the command you want to run in the container and it runs it there. So you just do
docker exec -i docker-name python xx.py config.yaml
and that runs the python command, prints any output and when the command ends, disconnects from the container again.
I've omitted the -t because that instructs docker to use the terminal (console), but Jenkins does not have any console, just the -i, instructing it to connect the stdin, stdout and stderr, is good enough.
Now there is also a way to send the commands on the standard input of the bash similar to what the console would do, but I strongly recommend reading the documentation of bash before attempting that.
I need to run a regression script in bash shell on a remote server. I am able to successfully connect and execute different commands using paramiko. But when I try to execute '/bin/bash' my Python script hangs forever:
stdin,stdout,stderr = ssh.exec_command("pwd;/bin/bash;echo $SHELL")
Without /bin/bash echo $SHELL works good and returns the following:
[u'/home/akar\n', u'/tools/cfr/bin/tcsh\n']
Is there any workaround?
My first doubt is what is the purpose of the bash you are executing. Literally it means:
pwd; #print '/home/akar\n' as it results
/bin/bash; #/bin/bash will take over of console(stdin/stdout/stderr) from here
echo $SHELL #when you input exit to exit the bash from line 2, line 3 will print
I need to run some bash commands via Fabric API (ssh).
I have the following String in my Python module:
newCommand = command + "'`echo -ne '\\015'"
When I print this string directly in Python the output is the expected:
command'`echo -ne '\015'
However, if I try to run this command via the Fabric API the command is somehow modified into this:
/bin/bash -l -c "command'\`echo -ne '\015'"
Notice the '\' before 'echo'. Why is this happenning? The '\' is breaking my command and I can't successfuly run the command.
ps: The prefix "/bin/bash -l -c" is expected since that's how Fabric works with SSH
This is not a valid shell command:
command'`echo -ne '\015'
Even if you add the missing backtick and single quote, it's nothing like writing "command" and pressing enter.
The context your command will be run in is basically what you'd get if you'd ssh and paste a command:
clientprompt$ ssh host
Welcome to Host, User
hostprompt$ <COMMAND HERE>
You should focus your efforts on finding a single command that does what you want, and not a series of keypresses that you could write to do it (that's not how ssh works).
I use python module pysftp to connect to remote server. Below you can see python code :
import pysftp
import sys
import sqr_common
srv = pysftp.Connection(host="xxxxxx", username="xxxx",
password="xxxxx")
command = "/usr/bin/bash"
command2="APSHOME=/all/aps/msc_2012; export APSHOME; "
srv.execute(command)
srv.execute(command2)
srv.close()
Problem is that command /usr/bin/bash is an infinite process , so my script will never be executed. Can anyone help me how to choose shell on remote server for example bash and execute command in bash on remote server?? Is there any pysftp function that allows me chosing shell??
try this
/usr/bin/bash -c "APSHOME=/all/aps/msc_2012; export APSHOME; "
This problem is not specific to Python, but more like how to execute commands under specific shell.
If you need to run only single command you can run using bash -c switch
bash -c "echo 123"
You can run multiple commands ; separated
bash -c "echo 123 ; echo 246"
If you need to many commands under a specific shell, remotely create a shell script file (.bash file) an execute it
bash myscript.bash
I've the following fabfile:
from fabric.api import *
env.hosts = ['samplehost']
env.user = 'foo'
env.password = 'bar'
env.shell = ''
def exec_ls():
run('ls')
run('ls -l')
and I get the following output:
[samplehost] Executing task 'exec_ls'
[samplehost] run: ls
[samplehost] out: sample.txt
[samplehost] run: ls -l
[samplehost] out: rbash: ls -l: command not found
Fatal error: run() encountered an error (return code 127) while executing 'ls -l'
Aborting.
Disconnecting from samplehost... done.
The login shell for user 'foo' is '/bin/rbash'.
It seems that if I execute a command with parameters it is treated as a single command (while 'ls' without parameters works perfectly).
Please note that I've put an empty shell because otherwise Fabric tries to use '/bin/bash' and that's not allowed by he restricted shell.
Is it possible to use Fabric in a restricted shell?
The problem isn't related to the fact that rbash is being used, but to the the empty value of env.shell. To fix that problem use:
env.shell = '/bin/rbash -l -c'
Note that:
the default value for env.shell is /bin/bash -l -c, so using /bin/rbash -l -c makes sense
when env.shell is set to the empty string, the command isn't executed through any shell
the shell is the one that takes care of splitting long strings into commands and arguments, without the shell all the string is interpreted as a single command that isn't going to be found as it was happening
In my environment, using a restricted shell as part of a Pure array, it appears an option would be to pass the argument shell=False to the run function.
-Check the environment of the target-machine with
echo $SHELL
.Hypothetically you get this:
/bin/sh
-Then in your python fabfile.py:
from fabric.api import env
env.shell = "/bin/sh -c"