Question

How can I redefine a command in a bash script so that a python script called from the bash script will execute the redefined version when called via pexpect?

test.sh

#!/bin/bash
function scp(){
    echo "Skip SCP"
}
export -f scp
python test.py

test.py

import pexpect
scp = pexpect.spawn("scp")
scp.expect([pexpect.EOF,pexpect.TIMEOUT],timeout=1500)
print scp.before    

In this example I expect (and want) to see is:

Skip SCP

but what I actually see is:

usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
           [-l limit] [-o ssh_option] [-P port] [-S program]
           [[user@]host1:]file1 ... [[user@]host2:]file2

I can change anything about the shell script, but the python comes from a third party and is copied into many different projects, so changing it would be impractical.

Was it helpful?

Solution

Most likely spawn executes it's commands directly (via execv or something) or it uses a specific shell like /bin/sh. If you want it to use a customized environment, you'll have to specify that yourself. I don't know pexpect, but something like

spawn bash
expect your_prompt
send "function scp { echo 'skip scp'; }"
expect your_prompt
send scp
expect "skip scp"

Additionally, bash functions are not exported to child processes unless you export -f scp


Since you can't touch the pexpect part, the only thing you can change is scp. You will have to provide a program named "scp" that occurs earlier in the path than the regular scp

#!/bin/sh
PATH=/my/special/path:$PATH
cat > /my/special/path/scp <<END
#!/bin/sh
echo "no scp here!"
END
chmod 755 /my/special/path/scp

python test.py
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top