I have a python script using 'subprocess' running linux command to confirm my task is doing the right thing, and it worked well. But i found that at the same time it will generate some log files when running my task. So i added a clean up function to rm log files for me at the beginning. My script is:
def test_clean_up_logs(path_to_my_log):
regex = path_to_my_log + ".*" # i need this because log will append current date time when it's generated
print(regex) # i can see it's correct
result = subprocess.run(['rm', '-rf', regex])
def test_my_real_test():
# This will run my real test and generate log files
but it turns out it did not remove log files for me after i added first test, it still have more and more logs file in my build dir. I run it using:
Python3.7 -m pytest /path/to/mydir
My question is:
1. Why did not it work? In my second test case, i am using 'subprocess' to run a linux command and it worked fine.
2. Is this correct way to clean up log files? i cannot think of a better way to do it automatically. Thanks!
Why did not it work?
Because the arguments that you gave to your command is passed in quotes and wildcards like * does not work in quotes. Currently the executed command looks like this:
$ rm "-rf" "filename.*"
Try this in your terminal and you will see that it will not remove the files that starts with filename..
You need to pass shell = True to execute the command in a shell interpreter and give your command as a single string.
subprocess.run(f'rm -rf {regex}', shell=True)
Related
Running on Windows system, I run bash.exe using subprocess.call().
Following is the code
def predict():
os.system('notepad cmnd.txt')
subprocess.call(['C:/Windows/System32/bash.exe'])
print(file_contents)
label = Label(master, text=file_contents)
#subprocess.call(['c:/users/hp/open.py'])
label.pack()
The handle passes to bash,thus not executing a couple of commands.
cd commands that runs on actually entering values return Missing Directory error.
ls command returns 'cannot run binary file' error.
What should I do?
I'm not really sure what you want here, but if you want to run bash commands in a Windows enviorment, you can try using subprocess.check_output():
from subprocess import check_output
bash_commands = ['ls', 'pwd']
for command in bash_commands:
output = check_output(['bash', '-c', command]).decode()
print(output)
Which in this example, lists all files in the current directory and prints out the parent working directory.
This is a beginner level question for anyone pro in subprocess.
In Windows, is it possible for me to send the following CMD commands using subprocesssuch that they are executed one after another in a single shell:
cd C:\Users\User\myvirtualenvs\project1
Scripts\activate.bat
Hello.py
Effectively, I am trying to load the Virtualenv without having to manually myself touch CMD prompt.
Thanks in advance :)
Just like mentioned in the Comment with &&:
from subprocess import call
call(r'cd C:\ && echo 123 && dir', shell=True)
Please notice the shell=True argument.
Edit due to comment:
Shell=True is an security issue, if you're passing raw input values to the call. See this example from the docs:
from subprocess import call
filename = input("What file would you like to display?\n")
>>> What file would you like to display?
>>> non_existent; rm -rf / #
call("cat " + filename, shell=True) # Uh-oh. This will end badly...
In initially thought you want to make a small script for personal purposes. If you want to give this code away, think about packaging your code via distutils or setuptools.
I am trying to run a python file that takes in one argument (CSV file). It works when i run the script in the terminal but it gives errors when i run it in cron.
This is the line that i run in the terminal:
python nb2.py my_csv_file.csv
And here is my code that i am trying to run in cron:
42 13 * * * /usr/local/bin/python2.7 ~/nb/Development/code/nb2.py ~/nb/Development/code/my_csv_file.csv &> /tmp/June_QB_cat.log
The error says that it cannot find a sqlite table file which is already in the code folder.
Note that when you run the command in the terminal, you're in the ~/nb/Development/code directory already and so your current working directory is that; when you run in it cron, it is not. I would suggest either doing (in your cron job) cd ~/nb/Development/code && python nb2.py my_csv_file.csv &> /tmp/logfile.txt or doing an os.chdir("~/nb/Development/code") as the first step in your code. (Also, I'd suggest doing /home/username instead of ~ just in case you aren't running cronjob as your username at some point, but given the error you get, that sounds like it's not an issue)
You can get the path of a file relative to the current script with
import os.path
relative_path = os.path.join( os.path.dirname(__file__), "sqlitetable" )
I am writing a test suite for a web application using Selenium.
In the course of which I need to test behaviour of the app in case a certain service is running or not.
I wanted to create a cgi call to a Python script turning that service on and off.
I know that the cgi call is in the context of the webserver (Apache) however thought that issuing sudo calls like so:
import subprocess
import os
command = 'sudo -S launchctl unload /Library/LaunchAgents/com.my.daemon.plist'
pwd = 'pwd123'
test1 = subprocess.Popen( command, shell=True, stdin=subprocess.PIPE)
test1.communicate(input=pwd)
test2 = os.system( 'echo %s|%s' % (pwd,command) )
would do the trick, well they don't I get return code 256.
What can I do to have this call be executed w/o touching the context in which Apache runs?
As for security: this will only run on a test machine.
The user that Apache runs as needs to be in the /etc/sudoers file, or belong to the sudo group, which I guess it usually doesn't. You also need to make it not ask for a password, which is configured in /etc/sudoers
For Ubuntu, check these out: https://askubuntu.com/questions/7477/how-can-i-add-a-new-user-as-sudoer-using-the-command-line
https://askubuntu.com/questions/147241/execute-sudo-without-password
It could potentially be a pathing issue..
Have you tried writing out the full path like this:
command = '/usr/bin/sudo -S launchctl unload /Library/LaunchAgents/com.my.daemon.plist'
command should be a list, not a string. Try with:
command = ['sudo', '-S', 'launchctl', 'unload', '/Library/LaunchAgents/com.my.daemon.plist']
Cant run sudo this way -- sudo needs a controlling terminal to run.
I need to get a path to the GIT on Max OS X 10.6 using Python 2.6.1 into script variables. I use this code for that:
r = subprocess.Popen(shlex.split("which git"), stdout=subprocess.PIPE)
print r.stdout.read()
but the problem is that output is empty (I tried stderr too). It works fine with another commands such as pwd or ls.
Can anyone help me with that?
UPDATE: When I run which git from Terminal it prints out path as expected. So, which can find it.
UPDATE 2: I just created the bash script
#!/usr/bin/env bash
GP=`/usr/bin/which git`
PWD=`pwd`
echo "PATH IS: ${GP}"
echo "PWD IS: ${PWD}"
and output is
PATH IS:
PWD IS: /Users/user/tmp
All which does is iterate over the directories in $PATH, checking to see if the file is there. Just write a small method to do likewise.