- How To Run Bash Commands In Python
- How to use os.system to run Bash Command
- How to use subprocess.check_output to run Bash Commands
- How to use subprocess.run to run Bash Commands
- Run Bash commands using Python Popen
- How to pipe commands together using Python Popen
- Wrap Up!
- How to Run bash scripts Using Python?
- Executing Bash Commands
- subprocess.run()
- subprocess.run() – input
- subprocess.Popen()
- wait
- communicate
- subprocess.Popen() – input
- poll
- Executing Bash Scripts
- Conclusion
- Как запустить bash скрипт из python?
How To Run Bash Commands In Python
There are different ways to run bash commands in Python. Lets start with os.system command.
How to use os.system to run Bash Command
Once we have imported the os. We can use os.system and pass it bash command. Lets try ls -ld /home command
The command is executed. We can’t capture the output with os.system
How to use subprocess.check_output to run Bash Commands
To see the output of executed command. There is another way. We need to import Python package subprocess.
import subprocess subprocess.check_output('ls -ld /home',shell=True, universal_newlines=True): 'drwxr-xr-x 14 root root 4096 Nov 28 16:12 /home\n'
How to use subprocess.run to run Bash Commands
To capture the output in a variable use the run method.
subprocess.run(['ls','-ld','/home'],check=True, stdout=subprocess.PIPE, universal_newlines=True): CompletedProcess(args=['ls', '-ld', '/home'], returncode=0, stdout='drwxr-xr-x 14 root root 4096 Nov 28 16:12 /home\n')
We can also capture the output in a variable
output = subprocess.run(['ls','-ld','/home'],check=True, stdout=subprocess.PIPE, universal_newlines=True)
output can be printed using following command.
output.stdout 'drwxr-xr-x 14 root root 4096 Nov 28 16:12 /home\n'
We can also printout the errors using following command.
check=True options throw an error if underlying option throws an error. Lets try again.
subprocess.run(['ls','-ld','/home1'],check=True, stdout=subprocess.PIPE, universal_newlines=True)
CalledProcessError: Command ‘[‘ls’, ‘-ld’, ‘/home1′]’ returned non-zero exit status 2.
Lets try without check=True option
subprocess.run(['ls','-ld','/home1'], stdout=subprocess.PIPE, universal_newlines=True) CompletedProcess(args=['ls', '-ld', '/home1'], returncode=2, stdout='')
Run Bash commands using Python Popen
Popen is used for complex commands, such as pipe commands in bash. Lets try a simple pipe command first.
p = subprocess.Popen(['ls','-ld','/home'],stderr=subprocess.PIPE, universal_newlines=True,stdout=subprocess.PIPE) out,err = p.communicate() print(out,err) drwxr-xr-x 14 root root 4096 Nov 28 16:12 /home
p is a Python process. We can query it anytime. Also we can close it.
Lets try accessing p again.
We got the following error.
ValueError: Invalid file object: _io.TextIOWrapper name=46 encoding='UTF-8'>
How to pipe commands together using Python Popen
Lets calculate number of files in the home directory.
p1 = subprocess.Popen(['ls','-lrt','/home'],stderr=subprocess.PIPE, universal_newlines=True,stdout=subprocess.PIPE) p2 = subprocess.Popen(["wc", "-l"], stdin=p1.stdout, stdout=subprocess.PIPE)
Note, how we have to query p1.stdout to find the output.
Now lets look at the output.
output = p2.communicate() print(output) (b'23\n', None)
Wrap Up!
I have discussed above 5 ways to run Bash commands in Python. There is another utility called pysh which can be used to run Bash commands.
How to Run bash scripts Using Python?
Invicti Web Application Security Scanner – the only solution that delivers automatic verification of vulnerabilities with Proof-Based Scanning™.
If you are using Linux, then you would definitely love the shell commands.
And if you are working with Python, then you may have tried to automate things. That’s a way to save time. You may also have some bash scripts to automate things.
Python is handy to write scripts than bash. And managing Python scripts are easy compared to bash scripts. You will find it difficult to maintain the bash scripts once it’s growing.
But what if you already have bash scripts that you want to run using Python?
Is there any way to execute the bash commands and scripts in Python?
Yeah, Python has a built-in module called subprocess which is used to execute the commands and scripts inside Python scripts. Let’s see how to execute bash commands and scripts in Python scripts in detail.
Executing Bash Commands
As you may have already seen the module subprocess is used to execute the bash commands and scripts. It provides different methods and classes for the same.
There are mainly one method and one class to know about from the subprocess module. They are run and Popen. These two help us to execute the bash commands in Python scripts. Let’s see them one by one.
subprocess.run()
The method subprocess.run() will take a list of strings as a positional argument. This is mandatory as it has the bash command and arguments for it. The first item in the list is the command name and the remaining items are the arguments to the command.
import subprocess subprocess.run(["ls"])
The above script list all the items in the current working directory as the script lies. There are no arguments to the command in the above script. We have given only the bash command. We can provide additional arguments to the ls command like -l , -a , -la , etc.
Let’s see a quick example with command arguments.
import subprocess subprocess.run(["ls", "-la"])
The above command displays all the files including hidden files along with the permissions. We have provided the argument la which displays files and directories extra information and hidden files.
We may end up making some mistakes while writing the commands. Errors will raise according to the mistakes. What if you want to capture them and use them later? Yeah, we can do that using the keyword argument stderr.
import subprocess result = subprocess.run(["cat", "sample.txt"], stderr=subprocess.PIPE, text=True) print(result.stderr)
Make sure you don’t have the file with the name sample.txt in the working directory. The value to the keyword argument stderr is PIPE which helps to return the error in an object. We can access it later with the same name. And the keyword argument text helps to tell that the output should be a string.
Similarly, we can capture the output of the command using the stdout keyword argument.
import subprocess result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) print(result.stdout)
subprocess.run() – input
You can give input to the commands using the input keyword argument. We will give inputs in a string format. So, we need to set the keyword argument text to True . By default, it takes it in bytes.
import subprocess subprocess.run(["python3", "add.py"], text=True, input="2 3")
In the above program, the Python script add.py will take two numbers as input. We have given the input to the Python script using the input keyword argument.
subprocess.Popen()
The class subprocess.Popen() is advanced than the method subprocess.run(). It gives us more options to execute the commands. We will create an instance of the subprocess.Popen() and use it for various things like knowing the status of the command execution, getting output, giving input, etc.
There are several methods of the class subprocess.Popen() that we need to know. Let’s see them one by one along with the code examples.
wait
It is used to wait until the completion of the execution of the command. The next lines of the Python script won’t execute until the completion of the previous command that is written after the wait method. Let’s see the example.
import subprocess process = subprocess.Popen(["ls", "-la"]) print("Completed!")
Run the above code and observe the output. You will see that the message Completed! is printed before the execution of the command. We can avoid it using the wait method. Let’s wait till the completion of the command.
import subprocess process = subprocess.Popen(["ls", "-la"]) process.wait() print("Completed!")
If you see the output for the above code, then you will realize that wait is actually working. The print statement is executed after the completion of the command execution.
communicate
The method communicate is used to get the output, error and give input to the command. It returns a tuple containing output and error respectively. Let’s see an example.
import subprocess process = subprocess.Popen(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) result = process.communicate() print(result)
subprocess.Popen() – input
We can’t pass the input to the class Popen directly. We need to use the keyword argument called stdin to give the input to the command. The instance of the class Popen will provide us stdin object. It has a method called write which is used to give the input to the command.
As we discussed earlier, it will take inputs as bytes-like objects by default. So, don’t forget to set the keyword argument text to True while creating the instance of Popen .
import subprocess process = subprocess.Popen(["python3", "add.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) process.stdin.write("2 3") process.stdin.close() print(process.stdout.read())
poll
The method poll is used to check whether the execution of the command is completed or not. This method will return None if the command is still executing. Let’s see an example.
import subprocess process = subprocess.Popen(['ping', '-c 5', 'geekflare.com'], stdout=subprocess.PIPE, text=True) while True: output = process.stdout.readline() if output: print(output.strip()) result = process.poll() if result is not None: break
In the above code, we have used the ping command with 5 requests. There is an infinite loop that iterates until the completion of the command execution. We have used the method poll to check the status of the command execution. If the method poll returns code other than None , then the execution completes. And the infinite loop breaks.
Executing Bash Scripts
We have seen two ways to execute the commands. Now, let’s see how to execute the bash scripts in Python scripts.
The subprocess has a method called call. This method is used to execute the bash scripts. The method returns the exit code from the bash script. The default exit code for the bash scripts is 0. Let’s see an example.
Create a bash script with the name practice.sh as follows.
#!/bin/bash echo "Hello, World!" exit 1
Now, write a Python script execute the above bash script.
import subprocess exit_code = subprocess.call('./practice.sh') print(exit_code)
You will get the following output once you run the above Python script.
Conclusion
We have seen how to execute bash commands and scripts in Python. You can use them to automate things more efficiently.
Как запустить bash скрипт из python?
Всем привет.
Подскажите пожалуйста, как правильно запустить bash скрипт, который лежит на компе через бота телеграм, который написан на питоне и получить ответ от него?
Если запускать сам скрипт через питон то работает, а через бот падает, не могу разобраться как правильно вывод результата организовать.
В обычном питон скрипте делал так:
import subprocess subprocess.call("test.sh")
proc = subprocess.Popen(‘./test.sh’, stdout=subprocess.PIPE)
output = proc.stdout.read()
print output
enabl3, Разбираться с вашим test.sh. Это он возвращает
$ cat hello.sh #!/bin/bash echo -n "Hello"
$ cat test.py #!/usr/bin/python import subprocess proc = subprocess.Popen('./hello.sh', stdout=subprocess.PIPE) output = proc.stdout.read() print output
Saboteur, все, в начале скрипта было clear что бы очищать все что было до этого, закомментил, все хорошо.
Огромное спасибо.
eegmak,
import subprocess
def ping(host):
param = ‘-t’ if platform.system().lower()==’windows’ else ‘-i’
command = [‘ping’, param, ‘0.2’, host]
return subprocess.call(command) == 0
#!/usr/bin/python import subprocess import shlex proc = subprocess.Popen(shlex.split('command arg1 arg2 arg3'), stdout=subprocess.PIPE) output = proc.stdout.read() print output
Firstline, Алексей Сергей, В общем случае есть консольное приложение (возможно неправильно называю его скриптом), оно должно быть запущено от sudo (знаю что писать свой пароль в открытом виде не оч, но любой способ подойдет) это приложение в консоль выводит циклически данные. это консольное приложение должно быть запущено с параметрами. выхлоп приложения нужно перехватывать в скрипте питона
eegmak, вариантов куча, навскидку:
— можно весь python скрипт запустить через sudo
— можно сделать, чтобы python скрпит передал пароль в дочерний процесс
— можно настроить sudo, чтобы «вот это конкретное» приложение не заправшивало пароль
— можно приложение запустить в качестве systemd сервиса и просто парсить логи потом
— может sudo вообще не нужен? просто добавить юзера в нужную группу и он получит доступ к файлам.
Алексей Сергей, попробовал добавить конкретное приложение в sudoers чтобы оно не запрашивало пароль, не получилось. Подскажите как реализовать вариант с передачей пароля внутри питон скрипта дочернему процессу. не совсем понимаю про systemd, мне нужно только парсить выхлоп приложения, а так я бы запустил его вручную, а позже подключился скриптом, если это вообще реализуемо..