I want to run two commands in sequence:
First go to /var/tmp/test folder
Then svn checkout here
In order to do that I wrote this script:
open_folder = "cd /var/tmp/%s" % (folder_name)
cmd = "%s %s/%s/%s && %s %s/%s/%s" % (svn_co, svn_co_directory, fst_product_name, fst_firmware_name, svn_co, svn_co_directory, snd_product_name, snd_firmware_name)
os.system(open_folder)
os.system(cmd)
It creates folder_name, but does not checkout into folder_name. It checked out to my current directory. Why?
Try os.chdir(path) to change the directory. Or you could use the folder as a prefix in your second command.
This explains, why cd won't work.
I would prefer to use subprocess.Popen(..) instead of os.system. It allows to specify a current working directory for the command you execute.
Related
Is there is way to show the current directory in IPython prompt?
Instead of this:
In [1]:
Something like this:
In<~/user/src/proj1>[1]:
You can use os.getcwd(current working directory) or in the native os command pwd.
In [8]: import os
In [9]: os.getcwd()
Out[9]: '/home/rockwool'
In [10]: pwd
Out[10]: '/home/rockwool'
Using ! before pwd will show the current directory
In[1]: !pwd
/User/home/
When interactive computing it is common to need to access the underlying shell. This is doable through the use of the exclamation mark ! (or bang) To execute a command when present in beginning of line.
According to:
https://ipython.org/ipython-doc/3/config/details.html#specific-config-details
In the terminal, the format of the input and output prompts can be customised. This does not currently affect other frontends.
So, in .ipython/profile_default/ipython_config.py, put something like:
c.PromptManager.in_template = "In<{cwd} >>>"
Assuming you're interested in configuring this for all subsequent invocations of ipython, run the following (in a traditional shell, like bash :) ). It appends to your default ipython configuration, creating it if necessary. The last line of the configuration file will also automatically make all the executables in your $PATH available to simply run in python, which you probably also want if you're asking about cwd in the prompt. So you can run them without a ! prefix. Tested with IPython 7.18.1.
mkdir -p ~/.ipython/profile_default
cat >> ~/.ipython/profile_default/ipython_config.py <<EOF
from IPython.terminal.prompts import Prompts, Token
import os
class MyPrompt(Prompts):
def cwd(self):
cwd = os.getcwd()
if cwd.startswith(os.environ['HOME']):
cwd = cwd.replace(os.environ['HOME'], '~')
cwd_list = cwd.split('/')
for i,v in enumerate(cwd_list):
if i not in (1,len(cwd_list)-1): #not last and first after ~
cwd_list[i] = cwd_list[i][0] #abbreviate
cwd = '/'.join(cwd_list)
return cwd
def in_prompt_tokens(self, cli=None):
return [
(Token.Prompt, 'In ['),
(Token.PromptNum, str(self.shell.execution_count)),
(Token.Prompt, '] '),
(Token, self.cwd()),
(Token.Prompt, ': ')]
c.TerminalInteractiveShell.prompts_class = MyPrompt
c.InteractiveShellApp.exec_lines = ['%rehashx']
EOF
(c.PromptManager only works in older versions of ipython.)
!dir shows the current directory and the contained files. The directory is shown with single backslashes, that simplifies the handling of the path (at least when using windows).
I have an .sh file that produces a picture on Raspberry Pi. and inside this file I have the following:
Config.sh:
#!/bin/bash
suffix=$(date +%H%M%S)
cd /home/pi/photobooth_images/
sudo cp image1.jpg /usb/photobooth_images/image-${suffix}-1.jpg
sudo convert -size 1800x1200 xc:white \
image1.jpg -geometry 1536x1152+240+24 -composite \
/home/pi/template/logo.png -geometry 192x1152+24+24 -composite \
PB_${suffix}.jpg
sudo cp PB_${suffix}.jpg /usb/photobooth_montage/PB_${suffix}.jpg
sudo rm /home/pi/photobooth_images/*
returnvalue=PB_${suffix}.jpg
echo "$returnvalue"
What I am trying to do here is get the PB_${suffix}.jpg "returnvalue" value (file name) it generated into Python. Now my Python program has this line, it runs the .sh file above.
Main.py:
return_value = subprocess.call("sudo ./" + config.sh, shell=True)
print "The Value is: " + str(return_value) + " This value from Python"
The output I get is this
[08:33:02 04-10-2016] [PHOTO] Assembling pictures according to 1a template.
PB_083302.jpg
The Value is: 0 This value from Python
The output I am expected should be something like "PB_070638.jpg"
Any help is greatly appreciated.
That is because subprocess.call only returns the return code of executing the script (documentation). You want the actual output of what your script returns, so you should be using check_output, and avoid using shell=True
subprocess.check_output(["sudo", "./", config.sh])
You also might want to revise running your script without root permission via sudo. It does not seem like something that should run using root privileges.
Try using the Popen constructor the with stdout arg:
subprocess.Popen(['"sudo ./" + config.sh'], stdout=subprocess.PIPE)
See also:
Get return value from shell command in python
Also, here's more info on Popen in the Python docs.
https://docs.python.org/2/library/subprocess.html#popen-constructor
I want to create a version of cd which will strip off a filename from a directory structure and then cd to that directory.
So for example if I put in the (tc)shell
cd /net/homes/me/myfile.jpg
it will strip off 'myfile.jpg' and cd to the directory structure. I tried this is my .cshrc:-
alias ccd '/net/homes/me/scripts/getDir.py'
Then my getDir.py file reads as:-
#! /usr/bin/python
import sys
import os
def get_dir():
the_dir = sys.argv[1]
dir_split = the_dir.split("/")
dir_count = len(the_dir.split("/"))
file_count = len(dir_split[dir_count-1])
only_dirs = the_dir[:-file_count]
#print only_dirs
os.chdir(only_dirs)
get_dir()
This strips off the filename part of the dir structure fine (I can tell that from the print statement) but the chdir command doesn't seem to work.
Thanks!
There's a standard binary called dirname which does this for you, so you can just use...
alias ccd 'cd `dirname \!:1`'
This works, can you explain the syntax?
Well, the dirname \!:1 part means to run the dirname program with the first argument passed to the aliased command, and the backticks substitute the output from that program into the cd command.
chdir doesn't change the state of the calling shell.
You need to change your alias to be something like this ( not sure of the exact tcsh syntax ):
alias ccd 'cd `getDir.py`'
Then your getDir script does nothing but print the correct path string ( no chdir needed )
How can I create a simple BAT file that will run my python script located at C:\somescript.py?
c:\python27\python.exe c:\somescript.py %*
Open a command line (⊞ Win+R, cmd, ↵ Enter)
and type python -V, ↵ Enter.
You should get a response back, something like Python 2.7.1.
If you do not, you may not have Python installed. Fix this first.
Once you have Python, your batch file should look like
#echo off
python c:\somescript.py %*
pause
This will keep the command window open after the script finishes, so you can see any errors or messages. Once you are happy with it you can remove the 'pause' line and the command window will close automatically when finished.
Here's how you can put both batch code and the python one in single file:
0<0# : ^
'''
#echo off
echo batch code
python "%~f0" %*
exit /b 0
'''
print("python code")
the ''' respectively starts and ends python multi line comments.
0<0# : ^ is more interesting - due to redirection priority in batch it will be interpreted like :0<0# ^ by the batch script which is a label which execution will be not displayed on the screen. The caret at the end will escape the new line and second line will be attached to the first line.For python it will be 0<0 statement and a start of inline comment.
The credit goes to siberia-man
Just simply open a batch file that contains this two lines in the same folder of your python script:
somescript.py
pause
If you've added Python to your PATH then you can also simply run it like this.
python somescript.py
You can use python code directly in batch file,
https://gist.github.com/jadient/9849314.
#echo off & python -x "%~f0" %* & goto :eof
import sys
print("Hello World!")
See explanation, Python command line -x option.
--- xxx.bat ---
#echo off
set NAME1="Marc"
set NAME2="Travis"
py -u "CheckFile.py" %NAME1% %NAME2%
echo %ERRORLEVEL%
pause
--- yyy.py ---
import sys
import os
def names(f1,f2):
print (f1)
print (f2)
res= True
if f1 == "Travis":
res= False
return res
if __name__ == "__main__":
a = sys.argv[1]
b = sys.argv[2]
c = names(a, b)
if c:
sys.exit(1)
else:
sys.exit(0)
Similar to npocmaka's solution, if you are having more than one line of batch code in your batch file besides the python code, check this out: http://lallouslab.net/2017/06/12/batchography-embedding-python-scripts-in-your-batch-file-script/
#echo off
rem = """
echo some batch commands
echo another batch command
python -x "%~f0" %*
echo some more batch commands
goto :eof
"""
# Anything here is interpreted by Python
import platform
import sys
print("Hello world from Python %s!\n" % platform.python_version())
print("The passed arguments are: %s" % sys.argv[1:])
What this code does is it runs itself as a python file by putting all the batch code into a multiline string. The beginning of this string is in a variable called rem, to make the batch code read it as a comment. The first line containing #echo off is ignored in the python code because of the -x parameter.
it is important to mention that if you want to use \ in your batch code, for example in a file path, you'll have to use r"""...""" to surround it to use it as a raw string without escape sequences.
#echo off
rem = r"""
...
"""
This is the syntax:
"python.exe path""python script path"pause
"C:\Users\hp\AppData\Local\Programs\Python\Python37\python.exe" "D:\TS_V1\TS_V2.py"
pause
Basically what will be happening the screen will appear for seconds and then go off take care of these 2 things:
While saving the file you give extension as bat file but save it as a txt file and not all files and Encoding ANSI
If the program still doesn't run save the batch file and the python script in same folder and specify the path of this folder in Environment Variables.
If this is a BAT file in a different directory than the current directory, you may see an error like "python: can't open file 'somescript.py': [Errno 2] No such file or directory". This can be fixed by specifying an absolute path to the BAT file using %~dp0 (the drive letter and path of that batch file).
#echo off
python %~dp0\somescript.py %*
(This way you can ignore the c:\ or whatever, because perhaps you may want to move this script)
ECHO OFF
set SCRIPT_DRIVE = %1
set SCRIPT_DIRECTORY = %2
%SCRIPT_DRIVE%
cd %SCRIPT_DRIVE%%SCRIPT_DIRECTORY%
python yourscript.py`
i did this and works:
i have my project in D: and my batch file is in the desktop, if u have it in the same drive just ignore the first line and change de D directory in the second line
in the second line change the folder of the file, put your folder
in the third line change the name of the file
D:
cd D:\python_proyects\example_folder\
python example_file.py
Use any text editor and save the following code as runit.bat
#echo off
title Execute Python [NarendraDwivedi.Org]
:main
echo.
set/p filename=File Name :
echo.
%filename%
goto main
Now place this file in the folder where python script is present. Run this file and enter python script's file name to run python program using batch file (cmd)
Reference : Narendra Dwivedi - How To Run Python Using Batch File
Create an empty file and name it "run.bat"
In my case i use "py" because it's more convenient, try:
C:
cd C:\Users\user\Downloads\python_script_path
py your_script.py
#echo off
call C:\Users\[user]\Anaconda3\condabin\conda activate base
"C:\Users\[user]\Anaconda3\python.exe" "C:\folder\[script].py"
start xxx.py
You can use this for some other file types.
I'm trying to implement my own version of the 'cd' command that presents the user with a list of hard-coded directories to choose from, and the user has to enter a number corresponding to an entry in the list. The program, named my_cd.py for now, should then effectively 'cd' the user to the chosen directory. Example of how this should work:
/some/directory
$ my_cd.py
1) ~
2) /bin/
3) /usr
Enter menu selection, or q to quit: 2
/bin
$
Currently, I'm trying to 'cd' using os.chdir('dir'). However, this doesn't work, probably because my_cd.py is kicked off in its own child process. I tried wrapping the call to my_cd.py in a sourced bash script named my_cd.sh:
#! /bin/bash
function my_cd() {
/path/to/my_cd.py
}
/some/directory
$ . my_cd.sh
$ my_cd
... shows list of dirs, but doesn't 'cd' in the interactive shell
Any ideas on how I can get this to work? Is it possible to change my interactive shell's current directory from a python script?
Change your sourced bash code to:
#! /bin/bash
function my_cd() {
cd `/path/to/my_cd.py`
}
and your Python code to do all of its cosmetic output (messages to the users, menus, etc) on sys.stderr, and, at the end, instead of os.chdir, just print (to sys.stdout) the path to which the directory should be changed.
my_cd.py:
#!/usr/bin/env python
import sys
dirs = ['/usr/bin', '/bin', '~']
for n, dir in enumerate(dirs):
sys.stderr.write('%d) %s\n' % (n+1, dir))
sys.stderr.write('Choice: ')
n = int(raw_input())
print dirs[n-1]
Usage:
nosklo:/tmp$ alias mcd="cd \$(/path/to/my_cd.py)"
nosklo:/tmp$ mcd
1) /usr/bin
2) /bin
3) ~
Choice: 1
nosklo:/usr/bin$
This can't be done. Changes to the working directory are not visible to parent processes. At best you could have the Python script print the directory to change to, then have the sourced script actually change to that directory.
For what its worth, since this question is also tagged "bash", here is a simple bash-only solution:
$ cat select_cd
#!/bin/bash
PS3="Number: "
dir_choices="/home/klittle /local_home/oracle"
select CHOICE in $dir_choices; do
break
done
[[ "$CHOICE" != "" ]] && eval 'cd '$CHOICE
Now, this script must be source'd, not executed:
$ pwd
/home/klittle/bin
$ source select_cd
1) /home/klittle
2) /local_home/oracle
Number: 2
$ pwd
/local_home/oracle
So,
$ alias mycd='source /home/klittle/bin/select_cd'
$ mycd
1) /home/klittle
2) /local_home/oracle
Number:
To solve your case, you could have the command the user runs be an alias that sources a bash script, which does the dir selection first, then dives into a python program after the cd has been done.
Contrary to what was said, you can do this by replacing the process image, twice.
In bash, replace your my_cd function with:
function my_cd() {
exec /path/to/my_cd.py "$BASH" "$0"
}
Then your python script has to finish with:
os.execl(sys.argv[1], sys.argv[2])
Remember to import os, sys at the beginning of the script.
But note that this is borderline hack. Your shell dies, replacing itself with the python script, running in the same process. The python script makes changes to the environment and replaces itself with the shell, back again, still in the same process. This means that if you have some other local unsaved and unexported data or environment in the previous shell session, it will not persist to the new one. It also means that rc and profile scripts will run again (not usually a problem).