This is kind of weird, but I am running a program called scrapebox, scrapebox has an automator plugin that creates a file to automagically run a few things within. In order to run the automator from cmd I would cd into the program directory then type:
Scrapebox.exe "automator:1.sbaf"
It would first launch Scrapebox the program, once open, it would immediately run the automated file.
This is a small piece in a much bigger puzzle. I am trying to call that within a larger Python script.
import os
import subprocess
..........
..........
..........
print "Opening Scrapebox now, please wait."
os.chdir('C:\Users\Admin\DomainDB\Programs\ScrapeBox')
print
print "Current working dir : %s" % os.getcwd()
print
subprocess.call(["Scrapebox.exe"])
#"automator:1.sbaf"
print "Scrapebox finished. Moving on."
When I run it as above, it works and opens scrapebox. But, what I really need to do is something like this:
subprocess.call(["Scrapebox.exe "automator:1.sbaf""])
When I do that it throws a syntax error. So how can I input that maybe as a raw string as though it were being typed into cmd?
If you want to embed double quotes in a string, you can use one of a number of ways. Also to pass a single string of all arguments, don't pass as a list []:
subprocess.call("Scrapebox.exe \"automator:1.sbaf\"")
subprocess.call('Scrapebox.exe "automator:1.sbaf"')
Python can use either single- or double-quotes around a string. You can also triple-quote a string (three single- or double-quotes at the start and end), which allows newlines as well, but it is not needed here.
If you pass a list of arguments, each argument should be an element of the list:
subprocess.call(['Scrapebox.exe','automator:1.sbaf'])
Related
I wanted to learn command line programming using Python.
I saw a to-do challenge on the internet and started to work on it by learning from the web. The challenge is to create a command line interface of a to-do app.
The challenge is titled CoronaSafe Engineering Fellowship Test Problem. Here is the challenge material on Google Drive: https://drive.google.com/drive/folders/1SyLcxnEBNRecIyFAuL5kZqSg8Dw4xnTG?usp=sharing
and there is a GitHub project at https://github.com/nseadlc-2020/package-todo-cli-task/
In the README.md I was instructed to create symbolic link for the batch file todo.bat with the name todo. Now, my first condition is that, when the symbolic link is called from the command prompt without any arguments, it must print some usage tips for the program. Finally, I have to use the npm test command to test the execution.
At the very beginning I got this trouble, whenever I use a print statement, I see a dot • at the end of every string which ends with a new line. For instance,
import sys
import random
args = sys.argv[1:]
if len(args) == 0:
print('Usage :-', end='\n')
print('$ ./todo help # Show usage', end='')
The above statements when executed without arguments gives the output,
Usage :-.
$ ./todo help # Show usage
Here, I noticed that for the first print statement ends with a newline, the string ends with what looks like a middle dot (•). Whereas, for the second print statement since I override the end parameter with an empty string, no newline character was output, and so the dot is not printed. See the screen shot:
What's wrong, and how can I pass the test? My program does not print a middle dot at all.
The problem seems to be squarely inside the todo.test.js file.
In brief, Windows and Unix-like platforms have different line ending conventions (printing a line in Windows adds two control characters at the end, whilst on Unix-like systems only one is printed) and it looks like the test suite is only prepared to cope with results from Unix-like systems.
Try forcing your Python to only print Unix line feeds, or switch to a free Unix-like system for running the tests.
Alternatively, rename todo.test.js and replace it with a copy with DOS line feeds. In many Windows text editors, you should be able to simply open the file as a Unix text file, then "Save As..." and select Windows text file (maybe select "ANSI" if it offers that, though the term is horribly wrong and they should know better); see e.g. Windows command to convert Unix line endings? for many alternative solutions (many of which vividly illustrate some of the other issues with Windows; proceed with caution).
This seems to be a known issue, as noted in the README.md you shared: https://github.com/nseadlc-2020/package-todo-cli-task/issues/12 (though it imprecisely labels this as "newline UTF encoding issues"; the problem has nothing to do with UTF-8 or UTF-16).
See also the proposed duplicate Line endings (also known as Newlines) in JS strings
I had exactly the same problem.
I replaced:
print(variable_name) # Or print("Your text here")
With:
sys.stdout.buffer.write(variable_name.encode('utf-8')) # To sys.stdout.buffer.write("Your text here".encode('utf-8'))
Now it worked fine in windows.
First write your help string like this
help_string='Usage :-\n$ ./task add 2 hello world # Add a new item with priority 2 and text "hello world" to the list\n$ ./task ls # Show incomplete priority list items sorted by priority in ascending order\n$ ./task del INDEX # Delete the incomplete item with the given index\n$ ./task done INDEX # Mark the incomplete item with the given index as complete\n$ ./task help # Show usage\n$ ./task report # Statistics'
Then print it on the console using
sys.stdout.buffer.write(help_string.encode('utf8'))
This problem occurs due to differences in encoding type of windows and npm tests. Also make sure to avoid any spaces after or before "\n".
Why have multiple prints,when python prints can incorporate new line without having to declare separately, follow example below:
print("Usage :- \n$ ./todo help #Show usage")
Output:
Usage :-
$ ./todo help #Show usage
I need a python script to call a bash script on windows.
So basically I must make a subprocess call form python, that will call cygwin with the -c option that will call the script I need,
The problem is that this script takes a few arguments and that these arguments are full os spaces and quotes and slashes.
I'm using code like the following
arq_saida_unix = arq_saida.replace("\\","/")
subprocess.call("C:\\cygwin64\\bin\\bash \".\\retirarVirgula.sh\\ \""+arq_saida+"\"")
Or I'm directly escaping, which sometimes takes me to as much as 8 backslashes in a row, for a backslash to get to my script must be escaped i) in bash ii) in cmd.exe iii) in python
all of this is error prone and takes quite some time every time to get it right.
Is there a better way of doing it? Ideally I wouldn't have any escaping backslashes, but anything that avoids the triple-slash double quote above would be nice.
I tried to use re.escape, but could figure out how exactly to use it , except as a replacement to .replace("\","/") and similar.
Don't pass a single string to call; instead, pass a list consisting of the command name and one argument per element. This saves you from needing to protect special characters from shell interpretation.
subprocess.call(["retirarVirgula.sh", arq_saida], executable=r"C:\cygwin64\bin\bash")
Note: I'm assuming arq_saida contains the single argument to pass to the script; if the script takes multiple arguments, then arc_saida should probably be built as a list as well:
arq_saida = ["arg", "arg two", "arg three"]
subprocess.call(["retirarVirgula.sh"] + arq_saida, executable=r"C:\cygwin64\bin\bash")
I'm trying to make a python script pass characters from a text file as keystrokes into OSX.
The text file is formatted as a column of characters:
Which is being read into a list (called lines). This bit seems to work, as when I type lines[3], for example, the third character is printed, as expected.
I'm now trying to use applescript to pass this character as a keystroke to OSX, using the following:
import os
for f in xrange ( VALUE ):
osascript -e 'tell application "System Events" to keystroke linesf]'
It doesn't seem happy about the list[f] part (syntax error, carat is beneath the final apostrophe). I suspect it's because the variable f is not available to this command, for some reason, but I'm not certain. Could anybody give any advice? I know that the bit in the for loop needs to be indented, but this dialogue won't let me indent it, for some reason. It is correct in the script that I am testing.
Thank in advance.
Edit:
Those were typos, it should be lines, not list, the colon should be there, and it should be indented. After fixing all of this, I have the same result. I can't just iterate through the list, this is only an excerpt of the for loop, it needs to be structured this way for the rest to work.
How do I fix the line beginning osascript?
I got this by editing the accepted answer from this question, by the way:
Is there a sendKey for Mac in Python?
What it's unhappy about is that you've tried to use a command line instruction within your Python program - Python sees osascript -e 'tell application "System Events" to keystroke list[f]' and thinks that you want to subtract e from osascript, but then has no idea what to do with the string 'tell application "System Events" to keystroke list[f]'.
There are many things you're doing wrong here. First off, the code you've posted can't possibly be what you actually have, because you're missing the colon from your for loop (it should be complaining about that instead) and haven't indented the code that goes inside your for loop. Second, you've imported os, which I assume you want in order to use os.system for your command line instruction. Third, you should not call a list list, because the name list is already in use for the actual list class (this is a useful thing to have around, because, for example, it lets you do things like list('foobar') to create the list ['f', 'o', 'o', 'b', 'a', 'r']). Fourth, if you want to loop over each item in a list, actually do that. Fifth, if you write a string like "keystroke x[y]", then the variables x and y (assuming they exist) are irrelevant: you've asked for the string to contain the actual letters 'x' and 'y' (and some square brackets). You need to actually build a string that contains the appropriate character from the list.
I want to pass url to my python via the console and then do the appropriate tasks. many of the links contain the character '&' in the link. python interprets that as ending the argument this however is not what I want. here is a sample of the code
import sys
external_id = sys.argv[1].encode("utf-8")
print external_id
And when I run the following:
python graph.py 2%60&7
I get:
2%60
How do I make python interpret the '&' as nothing more than another character in the url?
This is not python, it's bash. You need to escape it:
python graph.py 2%60\&7
Quoting this answer:
The & informs the shell to put the command in the background.
Python never receives that character because the shell takes care of it, thus this isn't an issue of Python. You can also wrap 2%60&7 with quotes to make it work
me#pc:~$ python3 script.py '2%60&7'
b'2%60&7'
Sometimes escaping & is a lot harder than doing this.
First time questioning here:
I have a need to map a network drive in windows. The location is an internal sharepoint document library.
In the cmd window:
net use g: http://na.com/DMP/DMP/programming/
is successfull --> the command completed succeffuly
os.system('"net use k: http://na.com/DMP/DMP/programming/"')
is also successful.
However i would like to use subprocess.call in the event that the drive is already mapped - i would like to try another drive
call(["net", "use", ":q", '"http://na.com/DMP/DMP/programming/"'])
This fails with "System error 67 has occured. The network name cannot be found"
I have tried many options for the last list item with no luck.
Any idea what I can stuff in there to have this complete successfully or a different method to map drives.
There are at least two problems in your code:
call(["net", "use", ":q", '"http://na.com/DMP/DMP/programming/"'])
First, you've got ":q" where you meant "q:". This might cause the net command to interpret :q as your network location instead of your target drive, which could cause an error 67.
Second, you've got an extra set of quotes around the URL: '"http://na.com/DMP/DMP/programming/"' where you should be using 'http://na.com/DMP/DMP/programming/'. When subprocess builds the string to pass to CreateProcess, it already quotes each of your parameters. So, if you quote them yourself, you end up double-quoting the parameters. There are some cases where this is actually not possible in Windows, so you end up with garbage, but I don't think that's the case here. You will successfully get this quoted string to net, telling it that you want to open either a relative path starting with "http: or a URL with protocol "http, or something like that. Whatever it is, it's not a usable network location, which most likely will cause an error 67.
As Ben pointed out, your system call has a similar problem—you put an extra pair of quotes around the entire string. If you really wanted to figure it out, there probably is some reason that this worked… but I don't think you want to figure it out. Just take it as "I did the wrong thing, but I got lucky", and don't do it that way in the future.
Finally, as the documentation says:
On Windows, an args sequence is converted to a string that can be parsed
This means that, if you already have a working command line for Windows, you're better off just using it as a string, than trying to break it down into a sequence for subprocess to reassemble.
(Keep in mind that this is only true for Windows! On other platforms, instead of building a command line string to pass to a function in the CreateProcess family, subprocess builds an array of strings to pass to a function in the exec family.)
So, just do this:
call("net use g: http://na.com/DMP/DMP/programming/")