(on os x 10.10.1)I am trying to use a paired-end merger (Casper) within a python script. i'm using os.system (don't want to use subprocess or pexpect modules). In my script here is the line that doesn't work:
os.system("casper %s %s -o %s"%(filein[0],filein[1],fileout))
#filein[0]: input file 1
#filein[1]: input file 2
#fileout: output prefix (default==casper)
Once my script is launched only the 2 first string parameters of this command are interpreted but not the third one, causing an output file with the default prefix name. Since my function is iterating through a lot of fastq files, they are all merged in a single "casper.fastq" file.
I tried to mess up with the part of the command that doesn't work (right after -o), putting meaningless string and still it is executed with no error and the default output, here is the "messed up line":
os.system("casper %s %s -ldkfnlqdskgfno %s"%(filein[0],filein[1],fileout))
Could anybody help in understanding what the heck is going on?
Print the command before execute it to check if your command wrapped correctly(like file name need to be quoted)
Execute your assumed output command directly to see if it is misinterpreted.
Related
Suppose I have a python file main.py, and it has some optional parameters, --learning-rate, --batch-size, and etc.
If I want to run this file, I can input the following into the terminal(Ubuntu Linux for example).
python3 main.py --learning-rate 0.1 --batch-size 100
And now, I want to write some code in main.py, in order that after I enter the command above, I can get this command in a string by executing those code. The following is the string I want to get:
"python3 main.py --learning-rate 0.1 --batch-size 100"
The reason I want to do this is that I want to write this string into my recording file so that I can know better what command I have run.
Could anyone tell me what package should I import and what code should I write to get that command information during running the python file?
Thanks!
You cannot always get precisely what you typed, because the shell will have first done substitutions and expanded filenames before starting your script. For example, if you type python "foo.py" *.txt, your script won't see *.txt, it will see the list of files, and it won't see the quotes around foo.py.
With that caveat out of the way, the sys module has a variable named argv that contains all of the arguments. argv[0] is the name of the script.
To get the name of the python executable you can use sys.executable.
To tie it all together, you can do something like this:
print(sys.executable + " " + " ".join(sys.argv))
Why not just remake the command using the arguments you parsed? It won't be exactly what you typed, but that might be nice as it will be in a common format.
Ex (assuming the learning rate and batch size are stored in similarly named variables):
command = "python3 main.py --learning-rate {} --batch-size {}".format(learning_rate, batch_size)
Of course it will be a little more complicated if some commands are optional, but I assume in that case there would be a default value for these parameters, since your network would need those parameters every time.
I am redirecting the output of a Python script to a file.
It works fine if there is no error.
But if there is any error , I wish to capture the error in another file which is not happening now.
Below is the script which I have written.
#echo off
mode con cp select=65001
set dt=%Date:~10,4%-%Date:~4,2%-%Date:~7,2%
cd C:\API_DOC\softeon_project\script
python -u softeon_main.py >>C:\API_DOC\softeon_project\log\log_%dt%.txt 2>>C:\API_DOC\softeon_project\log\logerr_%dt%.txt
echo "after python path"
pause
exit
Any help would be appreciable.
The usage of dynamic environment variable DATE depends on Windows Region setting as defined for the currently used user account.
For example with getting Tue 12/26/2017 written into a command prompt window on running in same window echo %DATE% it is possible to use either
set "dt=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%"
or better
set "dt=%DATE:~-4%-%DATE:~-10,2%-%DATE:~-7,2%"
Both command lines use string substitutions to get environment variable dt defined with string 2017-12-26. The difference is that the first command line references the characters in date string from left while the second command line references them from right. Therefore the second command line works also with no abbreviated weekday at beginning.
The help output for command SET on running set /? in a command prompt window explains string substitutions as used here.
A region independent solution to get current local date in format yyyy-MM-dd would be:
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "dt=%%I"
set "dt=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%"
This variant is explained in detail in answer on Why does %date% produce a different result in batch file executed as scheduled task?
The disadvantage is that WMIC takes more than a second to output the local date and time which makes this solution much slower than the solution using dynamic environment variable DATE.
I suggest to use:
#echo off
rem Define encoding UTF-8 for console.
%SystemRoot%\System32\mode.com CON CP SELECT=65001
rem Get current local date in format yyyy-MM-dd.
set "dt=%DATE:~-4%-%DATE:~-10,2%-%DATE:~-7,2%"
rem Change the current directory independent on current drive.
cd /D C:\API_DOC\softeon_project\script
rem Execute Python interpreter and redirect standard output messages
rem to file log_%dt%.txt and error messages to logerr_%dt%.txt.
python.exe -u softeon_main.py >>C:\API_DOC\softeon_project\log\log_%dt%.txt 2>>C:\API_DOC\softeon_project\log\logerr_%dt%.txt
echo "After python path"
pause
There was a trailing space in Python command line which is removed in code above. See the answers on Why does ECHO command print some extra trailing space into the file? and
Why is no string output with 'echo %var%' after using 'set var = text' on command line? why a trailing space in a batch file could result in an unexpected output into a file or even unexpected behavior on execution of a batch file.
And python was extended with file extension .exe to avoid that by chance a file python.bat or python.cmd is found first by Windows command interpreter as in this case the next line would not be executed anymore because batch files must be called from within a batch file with command CALL to return to calling batch file on finishing execution of called batch file.
Read also the Microsoft article about Using command redirection operators for an explanation of >> and 2>>.
First of all, I am new to programming.
To run python code in an external shell window, I followed the instructions given on this page
link
My problem is that if I save the python file in any path that contains a folder name with a space, it gives me this error:
C:\Python34\python.exe: can't open file 'C:\Program': [Errno 2] No such file or directory
Does not work:
C:\Program Files\Python Code
Works:
C:\ProgramFiles\PythonCode
could someone help me fix the problem???
Here is the code:
import sublime
import sublime_plugin
import subprocess
class PythonRunCommand(sublime_plugin.WindowCommand):
def run(self):
command = 'cmd /k "C:\Python34\python.exe" %s' % sublime.active_window().active_view().file_name()
subprocess.Popen(command)
subprocess methods accept a string or a list. Passing as a string is the lazy way: just copy/paste your command line and it works. That is for hardcoded commands, but things get complicated when you introduce parameters known at run-time only, which may contain spaces, etc...
Passing a list is better because you don't need to compose your command and escape spaces by yourself. Pass the parameters as a list so it's done automatically and better that you could do:
command = ['cmd','/k',r"C:\Python34\python.exe",sublime.active_window().active_view().file_name()]
And always use raw strings (r prefix) when passing literal windows paths or you may have some surprises with escape sequences meaning something (linefeed, tab, unicode...)
In this particular case, if file associations are properly set, you only need to pass the python script without any other command prefix:
command = [sublime.active_window().active_view().file_name()]
(you'll need shell=True added to the subprocess command but it's worth it because it avoids to hardcode python path, and makes your plugin portable)
I'm trying to make some functions in python so that I can connect to a linux terminal and do stuff (like in this case, create a file). The code I have, works partially. The only thing that doesn't work is if you want to do something after you have entered the code. Like for instance you create the file and then want to navigate somewhere else (cd /tmp) for instance. Instead of doing the next command, it will just add to the file created.
def create_file(self, name, contents, location):
try:
log.info("Creating a file...")
self.device.execute("mkdir -p {}".format(location))
self.cd_path(location)
self.device.sendline("cat > {}".format(name))
self.device.sendline("{}".format(contents))
self.device.sendline("EOF") # send the CTRL + D command to save and exit I tried here with ^D as well
except:
log.info("Failed to create the file!")
The contents of the file is:
cat test.txt
#!/bin/bash
echo "Fail Method Requested"
exit 1
EOF
ls -d /tmp/asdasd
The order of commands executed is:
execute.create_file(test.txt, the_message, the_location)
execute.check_path("/tmp/adsasd") #this function just checks with ls -d if the directory exists.
I have tried with sendline the following combinations:
^D, EOF, <<EOF
I don't really understand how I could make this happen. I just want to create a file with a specific message. (When researching on how to do this with VI I got the same problem, but there the command I needed was the one for ESC)
If anyone could help with some input that would be great!!
Edit: As Rob mentioned below, sending the character "\x04" actually works. For anyone else having this issue, you can also consult this chart for other combinations if needed:
http://donsnotes.com/tech/charsets/ascii.html
You probably need to send the EOF character, which is typically CONTROL-D, not the three characters E, O, and F.
self.device.sendline("\x04")
http://wiki.bash-hackers.org/syntax/redirection#here_documents
Here docs allow you to use any file input termination string you like to represent end of file ( such as the literal EOF you're attempting to use now). Quoting that string tells the shell not to interpret expansions inside the heredoc content, ensuring that said content is treated as literal.
Using pipes.quote() here ensures that filenames with literal quotes, $s, spaces, or other surprising characters won't break your script. (Of course, you'll need to import pipes; on Python 3, by contrast, this has moved to shlex.quote()).
self.device.sendline("cat > {} <<'EOF'".format(pipes.quote(name)))
Then you can write the EOF as is, having told bash to interpret it as the end of file input.
I am trying to write a small program in bash and part of it needs to be able to get some values from a txt file where the different files are separated by a line, and then either add each line to a variable or add each line to one array.
So far I have tried this:
FILE=$"transfer_config.csv"
while read line
do
MYARRAY[$index]="$line"
index=$(($index+1))
done < $FILE
echo ${MYARRAY[0]}
This just produces a blank line though, and not what was on the first line of the config file.
I am not returned with any errors which is why I am not too sure why this is happening.
The bash script is called though a python script using os.system("$HOME/bin/mcserver_config/server_transfer/down/createRemoteFolder"), but if I simply call it after the python program has made the file which the bash script reads, it works.
I am almost 100% sure it is not an issue with the directories, because pwd at the top of the bash script shows it in the correct directory, and the python program is also creating the data file in the correct place.
Any help is much appreciated.
EDIT:
I also tried the subprocess.call("path_to_script", shell=True) to see if it would make a difference, I know it is unlikely but it didn't.
I suspect that when calling the bash script from python, having just created the file, you are not really finished with that file: you should either explicitly close the file or use a with construct.
Otherwise, the written data is still in any buffer (from the file object, or in the OS, or wherever). Only closing (or at least flushing) the file makes sure the data is indeed in the file.
BTW, instead of os.system, you should use the subprocess module...