Jenkins Execute shell behaving differently - python

I am creating a Jenkins project which executes a shell on build. Inside the execute shell I am running a python script like
`python3 pythonScriptFile.py "${arg1}" "${arg2}" "${arg3}"
the python file internal call a shell script.
python -> shell1 -> shell2 -> return back to python file to continue execution.
when i execute the python file with arguments in terminal the the execution is synchronous one after the other.
but when I run the same in Jenkins first the shell is executed then the python file.
`print("SCRIPT Started")
process = os.system("""sh script.sh -t {arg1} -e {arg2}""")
process.wait()
if process.returncode != 0:
sys.exit()
print("Error executing build script")
print("SCRIPT COMPLETED")`
Output:
Script executed (which is a echo inside shell)
SCRIPT Started
SCRIPT COMPLETED`
Expected Output:
SCRIPT Started
Script executed (which is a echo inside shell)
SCRIPT COMPLETED`

[ Why does that happen ? ]
The buffering of a standard output stream depends on the environment and program settings.
In Jenking the output stream of python program is fully buffered, while interactive program connected to a terminal is line buffered.
[ How to fix it ? ]
Disable output buffering

Related

How to send keys to a python pdb shell from bash script?

I am trying to create a bash script that runs a python3 script with pdb trace set. As such, in my bash script I have the following lines:
python3 path/to/my_script.py
n
What I want to happen is for bash to run the python script, which will then open the python debugger. Then, the bash script will send the key 'n' to the pdb shell so that pdb executes the first line in the python script.
The script does not work as expected and bash waits until the python script has completed (or exited) to execute 'n' in the command line which just opens node.
I thought this might be a problem unique to pdb shells so I tried executing the following in bash:
python3
print("Hello")
However, again, we observe that the script creates a python3 shell and then waits for the shell to exit before executing print("Hello") in the terminal. I understand that I could use python3 -c for this case, but that does not address the case of passing commands to the pdb shell in the context of the running script.
Is there any way to send the 'n' command to the pdb shell that the python script generates?
Your code will try to run two commands. First, it will run your python script, then it will try to run a command called n. Assuming your script needs you read from stdin you can do one of the following:
Use a herestring:
python3 path/to/my_script.py <<< "n"
Use a pipeline:
One example echo "n" | python3 path/to/my_script.py
Echo is not the only command you can use. You can also use printf or even yes for this use case.
You can use a coprocess to send and receive from pdb.
#! /bin/bash
send() {
echo "$1" >&${PDB[1]}
}
recv() {
IFS= read -r -u ${PDB[0]} line
echo $line
}
coproc PDB { /path/to/my_script.py; }
send 'n'
recv
#...
send 'n'
recv

Windows only writes to file after process is stopped

I wrote a really simple script to test out the redirection of windows machine stdout. The program is as such
# hw.py
def main():
print('Hello World')
import time
time.sleep(1000)
if __name__ == '__main__':
main()
I ran this script using the following command.
python3 hw.py > hw.log
By observing in real time hw.log using either tail -f on git bash or opening an emacs buffer, I noticed that 'Hello World' is only printed to hw.log when the process ends, or it is cancelled prematurely.
This means that I cannot have a live view of a program output while writing it to a file.
Worst still, if my program consists of infinite child processes, any output from the program will not be written to the file
How do I resolve this?
To force the Python stdout and stderr streams to be unbuffered you can pass the -u argument.
python3 -u hw.py > hw.log
Setting the environment variable PYTHONBUFFERRED=1 will have the same effect

redirecting the output of a python command to a txt file working in cmd but not in .bat file, how to solve?

well I'm trying to make a logger for my python script using a runner in a '.bat' format, that executes the script and saves an output file; without me having to do it manually.
when I tried to run my python script, script.py, and pass 20 as an argument for the script as well as redirecting the output to a log_file.txt, using windows command prompt, it worked just fine, and the log file was created.
~the cmd command:
python script.py 20 >> log_file.txt
But when I tried to run the same code using the runner ".bat" file it didn't work.
~The codes I've written inside the "runner.bat" is as follows
python script.py 20 >> log_file.txt
pause
~but the execution command is done by the bat file was-as seen from the screen-:
C:\Users\dahom\Desktop\folder>python script.py 1>>log_file.txt
I expected the ".bat" file to behave the same save the log_file as the cmd terminal.
But when I ran the bat file it didn't redirect the output to the log_file.txt
But it seems to be running the script, without but one indication that it takes some time for the script running.
note: both the batch file and the script are in the same folder/dir/path.
HERE is an image showing everything.
TRY:
#echo off
"C:\Users\dahom\AppData\Local\Programs\Python\Python37-32\python.exe" "C:\Users\dahom\Desktop\new.py" >> "C:\Users\dahom\Desktop\log_file.txt" & type "C:\Users\dahom\Desktop\log_file.txt"
pause
NEW.py:-
print("Echo Fox")
OUTPUT OF THE BATCH SCRIPT:-
Echo fox
Press any key to continue . . .
WORKING:-
Just Provide the full paths of each file used in the command (python exec, python script, text file etc). When the command get's pipe'd to file use & type "file_path" to display the contents of the file after writing it.

Open new gnome-terminal and run command

I'm trying to write a script that opens a new terminal then runs a separate python script from that terminal.
I've tried:
os.system("gnome-terminal 'python f.py'")
and
p = Popen("/usr/bin/gnome-terminal", stdin=PIPE)
p.communicate("python f.py")
but both methods only open a new terminal and do not run f.py. How would I go about opening the terminal AND running a separate script?
Edit:
I would like to open a new terminal window because f.py is a simply server that is running serve_forever(). I'd like the original terminal window to stay "free" to run other commands.
Like most terminals, gnome terminal needs options to execute commands:
gnome-terminal [-e, --command=STRING] [-x, --execute]
You probably need to add -x option:
x, --execute
Execute the remainder of the command line inside the terminal.
so:
os.system("gnome-terminal -x python f.py")
That would not run your process in the background unless you add & to your command line BTW.
The communicate attempt would need a newline for your input but should work too, but complex processes like terminals don't "like" being redirected. It seems like using an interactive tool backwards.
And again, that would block until termination. What could work would be to use p.stdin.write("python f.py\n") to give control to the python script. But in that case it's unlikely to work.
So it seems that you don't even need python do to what you want. You just need to run
python f.py &
in a shell.
As of GNOME Terminal 3.24.2 Using VTE version 0.48.4 +GNUTLS -PCRE2
Option “-x” is deprecated and might be removed in a later version of gnome-terminal.
Use “-- ” to terminate the options and put the command line to execute after it.
Thus the preferred syntax appears to be
gnome-terminal -- echo hello
rather than
gnome-terminal -x echo hello
Here is a complete example of how you would call a executable python file with subprocess.call Using argparse to properly parse the input.
the target process will print your given input.
Your python file to be called:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--file", help="Just A test", dest='myfile')
args = parser.parse_args()
print args.myfile
Your calling python file:
from subprocess import call
#call(["python","/users/dev/python/sandboxArgParse.py", "--file", "abcd.txt"])
call(["gnome-terminal", "-e", "python /users/dev/python/sandboxArgParse.py --file abcd.txt"])
Just for information:
You probably don't need python calling another python script to run a terminal window with a process, but could do as follows:
gnome-terminal -e "python /yourfile.py -f yourTestfile.txt"
The following code will open a new terminal and execute the process:
process = subprocess.Popen(
"sudo gnome-terminal -x python f.py",
stdout=subprocess.PIPE,
stderr=None,
shell=True
)
I am running a uWS server with this.In my case Popen didn't help(Even though it run the executable, still it couldn't communicate with a client -: socket connection is broken).This is working.Also now they recommends to use "--" instead of "-e".
subprocess.call(['gnome-terminal', "--", "python3", "server_deployment.py"])
#server_deployment.py
def run():
execution_cmd = "./my_executable arg1 arg2 dll_1 dll_2"
os.system(execution_cmd)
run()

Have python script run in background of unix

I have a python script that I want to execute in the background on my unix server. The catch is that I need the python script to wait for the previous step to finish before moving onto the next task, yet I want my job to continue to run after I exit.
I think I can set up as follows but would like confirmation:
An excerpt of the script looks like this where command 2 is dependent on the output from command 1 since it outputs an edited executable file in same directory. I would like to point out that commands 1 and 2 do not have the nohup/& included.
subprocess.call('unix command 1 with options', shell=True)
subprocess.call('unix command 2 with options', shell=True)
If when I initiate my python script like so:
% nohup python python_script.py &
Will my script run in the background since I explicitly did not put nohup/& in my scripted unix commands but instead ran the python script in the background?
yes, by running your python script with nohup (no hangup), your script won't keel over when the network is severed and the trailing & symbol will run your script in the background.
You can still view the output of your script, nohup will pipe the stdout to the nohop.out file. You can babysit the output in real time by tailing that output file:
$ tail -f nohop.out
quick note about the nohup.out file...
nohup.out The output file of the nohup execution if
standard output is a terminal and if the
current directory is writable.
or append the command with & to run the python script as a deamon and tail the logs.
$ nohup python python_script.py > my_output.log &
$ tail -f my_output.log
You can use nohup
chomd +x /path/to/script.py
nohup python /path/to/script.py &
Or
Instead of closing your terminal, use logout It is not SIGHUP when you do logout thus the shell won't send a SIGHUP to any of its children.children.

Categories

Resources