executable python file sys not accepting '(' character - python

I am trying to write a python file that takes command line input and performs some actions. The input will consist of a-z, [, ], ( and ). I made the following program just to check that I could keep going:
#!/usr/bin/env python
import sys
print str(sys.argv)
I did chmod +x program and tried calling ./program qwerty (abc) [hi] and it returned:
-bash: syntax error near unexpected token `('
Is there any way of changing the program so that it accepted parentheses in arguments?
Note: I have also tried placing square brackets before parentheses and it returns the same error.

There's nothing the script can do about shell syntax when invoking the script. The shell parses the command line first. You have to escape or quote characters that have special meaning in the shell (which includes most punctuation characters):
./program qwerty \(abc\) '[hi]'

Related

Safely echo python commands into file without executing them

So I have a python file with a ton of lines in it that I want to read into python then echo into another file over a socket.
Assuming I have file foo.py
import os
os.popen('some command blah')
print("some other commands, doesn't matter")
Then I try and open the file, read all the lines, and echo each line into a new file.
Something along the lines of
scriptCode = open(os.path.realpath(__file__)).readlines()
for line in scriptCode:
connection.send("echo " + line + " >> newfile.py")
print("file transfered!")
However, when I do this, the command is executed in the remote shell.
So my question:
How do I safely echo text into a file without executing any keywords in it?
What have I tried?
Adding single quotes around line
Adding single quotes around line and then a backslash to single quotes in line
Things I've considered but haven't tried yet:
Base64 encoding the line until on the remote machine then decoding it (I don't want to do this because there's no guarentee it'll have this command)
I know this is odd. Why am I doing this?
I'm building a pentesting reverse shell handler.
shlex.quote will:
Return a shell-escaped version of the string s. The returned value is a string that can safely be used as one token in a shell command line, for cases where you cannot use a list.
Much safer than trying to quote a string by yourself.

Send literal string from python-vim script to a tmux pane

I am using Vim (8.0) and tmux (2.3) together in the following way: In a tmux session I have a window split to 2 panes, one pane has some text file open in Vim, the other pane has some program to which I want to send lines of text. A typical use case is sending lines from a Python script to IPython session running in the other pane.
I am doing this by a Vim script which uses python, code snippet example (assuming the target tmux pane is 0):
py import vim
python << endpython
cmd = "print 1+2"
vim_cmd = "silent !tmux send-keys -t 0 -l \"" + cmd + "\"" # -l for literal
vim.command(vim_cmd)
endpython
This works well, except for when cmd has some characters which has to be escaped, like %, #, $, etc. The cmd variable is read from the current line in the text file opened in Vim, so I can do something like cmd = cmd.replace('%', '\%') etc., but this has 2 disadvantages: first, I don't know all the vim characters which have to be escaped, so it has been trial and error up until now, and second, the characters " is not escaped properly - that is in the string Vim gets, the " just disappears, even if I do cmd = cmd.replace('"', '\"').
So, is there a general way to tell Vim to not interpret anything, just get a raw string and send it as is? If not, why is the " not escaped properly?
Vimscript
You're looking for the shellescape() function. If you use the :! Vim command, the {special} argument needs to be 1.
silent execute '!tmux send-keys -t 0 -l ' . shellescape(cmd, 1)
But as you're not interested in (displaying) the shell output, and do not need to interact with the launched script, I would switch from :! to the lower-level system() command.
call system('tmux send-keys -t 0 -l ' . shellescape(cmd))
Python
The use of Python (instead of pure Vimscript) doesn't have any benefits (at least in the small snippet in your question). Instead, if you embed the Python cmd variable in a Vimscript expression, now you also need a Python function to escape the value as a Vimscript string (something like '%s'" % str(cmd).replace("'", "''"))). Alternatively, you could maintain the value in a Vim variable, and access it from Python via vim.vars.

Conditional Statements using "cmd python -c" — How can I pass `if`?

I have written a batch script that prompts the user for an input and displays the help for a specific library ExternalLibrary. However, I receive the error below the code sample.
#echo off
set input=NUL
set /p input="Help: "
python -c "import sys; sys.path.append('D:\\lib'); import ExternalLibrary;lookup = ExternalLibrary.Presentation_control();if ('%input%' == 'NUL'):& help(lookup.%input%)&else:& help(lookup)"
A working version can be achieved by replacing the if statement with:
help(lookup.%input%)
Error in the column that starts with if
C:\Users\usah>Lib_Help.cmd
Help:
File "<string>", line 1
import sys; sys.path.append('D:\\lib'); import ExternalLibrary;lookup = ExternalLibrary.Presentation_control();if ('NUL' == 'NUL'):& help(lookup.NU
L)&else:& help(lookup)
^
SyntaxError: invalid syntax
Footnotes
1. I am note sure whether I should pass &, \n, or ; as newline
2. These related answers are not satisfying as they use workarounds.
Only simple statements can be written on single line separated by semicolons
This was more interesting than it seemed. For the sake of unambiguity you can't write conditional or any other compound statement on semicolon separated single line.
Simple statements
Compound statements
Your options
Rewrite it all to Python
This should not be so hard. Use sys.argv for arguments and
getattr(lookup, "something")
instead of your
lookup.%input%
sys.argv
getattr
Use linefeeds
Write multiline Python script on one cmd line. You can do it using !LF! special.
#echo off
setlocal enableDelayedExpansion
set LF=^
set input=NUL
set /p input="Help: "
python -c "import sys!LF!sys.path.append('D:\\lib')!LF!import ExternalLibrary!LF!lookup = ExternalLibrary.Presentation_control()!LF!if ('%input%' == 'NUL'):!LF! help(lookup)!LF!else:!LF! help(lookup.%input%)!LF!"

Maya ignores my doubles quotations

I'm having troubles starting maya from a python script with a mel command. Or rather I have a problem getting the mel command to run, maya launches just fine.
This is what the maya documentation says about starting with a mel command:
-command [mel command]
Runs the specified command on startup. The command should be enclosed
in double quotes to protect any special characters, including spaces.
Whatever I try Maya just ignores my doublequotes and gives me a syntax error.
This is my code:
import os
dir = "D:\exampleProject\maya"
os.system('maya.exe -command \"setProject \"'+dir+'\"\"')
I figure this would be read as this in maya: setProject "D:\exampleProject\maya" (which is what I want)
What I get is instead: setProject D:\exampleProject\maya which generates a syntax error in maya due to the lack of "" around the directory path.
Answer from comments
From the MEL documentation, it states that "Every statement in MEL must end with a semi-colon (;)."
MEL strings also require quotations to be escaped, therefore double escape the internal quotations.
'maya.exe -command \"setProject \\\"'+dir+'\\\";\"'
If all you need is to set the project you can use the startup flag "-proj"
maya.exe the/scene/iwant/to/open.ma -proj the/project/root
See the Documentation

check_call and command line arguments on Windows

My python program is invoking a script on Windows using check_call:
import subprocess
subprocess.check_call(['my_script.bat', 'foo=bar'])
I expect my_script.bat to receive a single command line argument (foo=bar), but is instead receiving two (foo and bar). In other words, it seems that the equal sign is being converted to whitespace. Everything works as expected on Linux.
What is the correct way to format this string on Windows such that my_script sees a single argument containing the equal sign?
my_script.bat:
echo %1
In my actual application, my_script.bat is scons.bat.
This case tests just fine for me under windows 7, using python2.7
my_script.py
import sys
print sys.argv
python shell
>>> import subprocess
>>> subprocess.check_call('python', 'my_script.py', 'arg1', 'foo=bar')
['myscript.py', 'arg1', 'foo=bar']
0
You may want to verify how your "my_script" is handling the incoming args.
Update
Since you have updated your question to reflect that you are specifically working with windows batch files, then here is the solution: http://geoffair.net/ms/batch.htm
Note: If a semicolon, ';' or an equal sign (=) is used as a command
line argument to a batch file, it is treated as a blank space. For
example, in the following test.bat batch file -
Equal sign is a special character that will be replaced with whitespace. It needs to be quoted:
subprocess.check_call(['my_script.bat', '"foo=bar"'])

Categories

Resources