How to use SublimeLinter's cmd attribute - sublime-text-plugin

I'm writing a SublimeLinter (a SublimeText plugin) plugin that uses luacheck for a custom syntax we use. So far I have it working with simply cmd = 'luacheck #', the # being apparently replaced by the filename when SublimeLinter calls luacheck. The problem is that with SublimeLinter on 'background' mode, the warnings don't actually update until the file is saved, e.g. if I remove a line containing a warning the warning will still be there, just highlighting a blank space (until I save, that is). I have a feeling that this is because I'm using the # and since this is replaced by the filename, luacheck won't update till the file is updated. However, the SublimeLinter documentation on cmd is not great, and I'm having trouble figuring out how to write one correctly. None of the plugins on their GitHub seem to use #, either. If I copy the default lua plugin (which uses cmd = 'luac -p * -') and use cmd = 'luacheck * -', luacheck executes but only returns an I/O error. Could someone maybe provide some more insight into how SublimeLinter's cmd attribute works?
EDIT: I was able to fix this issue by using tempfile_suffix = 'lua' in linter.py. According to the SublimeLinter docs, this is used for linters that don't use stdin, so I suppose my issue could have been with luacheck instead.

I was able to fix this issue by using tempfile_suffix = 'lua' in linter.py. According to the SublimeLinter docs, this is used for linters that don't use stdin, so I suppose my issue could have been with luacheck instead.

Related

Receiving back string of lenght 0 from os.popen('cmd').read()

I am working with a command line tool called 'ideviceinfo' (see https://github.com/libimobiledevice) to help me to quickly get back serial, IMEI and battery health information from the iOS device I work with daily. It executes much quicker than Apple's own 'cfgutil' tools.
Up to know I have been able to develop a more complicated script than the one shown below in PyCharm (my main IDE) to assign specific values etc to individual variables and then to use something like to pyclip and pyautogui to help automatically paste these into the fields of the database app we work with. I have also been able to use the simplified version of the script both in Mac OS X terminal and in the python shell without any hiccups.
I am looking to use AppleScript to help make running the script as easy as possible.
When I try to use Applescript's "do shell script 'python script.py'" I just get back a string of lenght zero when I call 'ideviceinfo'. The exact same thing happens when I try to build an Automator app with a 'Run Shell Script' component for "python script.py".
I have tried my best to isolate the problem down. When other more basic commands such as 'date' are called within the script they return valid strings.
#!/usr/bin/python
import os
ideviceinfoOutput = os.popen('ideviceinfo').read()
print ideviceinfoOutput
print len (ideviceinfoOutput)
boringExample = os.popen('date').read()
print boringExample
print len (boringExample)
I am running Mac OS X 10.11 and am on Python 2.7
Thanks.
I think I've managed to fix it on my own. I just need to be far more explicit about where the 'ideviceinfo' binary (I hope that's the correct term) was stored on the computer.
Changed one line of code to
ideviceinfoOutput = os.popen('/usr/local/bin/ideviceinfo').read()
and all seems to be OK again.

python subprocess popen returns None

I have a python snippet like this:
self.task = subprocess.Popen("bash ./FOLDER/script.sh", cwd=some_dir, shell=True)
self.task.wait()
from which an exception is raised, complaining that a 'NoneType' object has no method wait(). I guess it means the Popen call returns None ? What could be the reason for that. The documentation does not mention this possibility
I'm using python 2.7.13
Well, apparently self.task gives a NoneType respons meaning the subprocess.Popen() command is likely at fault.
First thing I notice is an incorrect syntax, since you did not wrap your command line in square brackets [] and you did not split the arguments.
Furthermore, the Python docs state (regarding the cwd option you used):
If cwd is not None, the child’s current directory will be changed to
cwd before it is executed. Note that this directory is not considered
when searching the executable, so you can’t specify the program’s path
relative to cwd.
So first thing to check would be if your script.sh is situated in some_dir/FOLDER/script.sh.
If that is indeed the case, please check if you inserted the cwd-argument with the right syntax, so as a string.. Meaning cwd="/path/to/some/dir".
Then, since the Python docs clearly state that:
Using shell=True can be a security hazard
I would remove that argument. This might mean you will have to use the full path to your bash. To find out the correct path, open a terminal and execute which bash. Or, to be sure, type bash.
Then, give this a try:
import subprocess
self.task = subprocess.Popen(["/path/to/your/bash", "./FOLDER/script.sh"], cwd="/path/to/some_dir", stdout=subprocess.PIPE, stderr=subprocess.PIPE) # This makes sure you will also catch any standard errors, so it allows for a bit more control.
output, errors = self.task.communicate() # This already encapsulates .wait()
print(output.decode()) # if you'd like to check the output.
Read the comments in code for some further explanation..

Wmic /format switch invalid XSL?

I have a quick question, should be relatively simple for those who have some more experience in WMI-command processor than I do (and since I'm an absolute beginner thats not hard :-) )
I fail to understand why wmic /format switch works the way it does. I open up cmd.exe and type
wmic process list brief /format:htable > processlist.html
this does exactly what I want and no bothers further on. Whereas if I go to wmic processor, and try to execute the same command exactly as above...
wmic:root\cli>process list brief /format:htable > processlist.html
I receive the error tag: "Invalid XSL format (or) file name."
Here goes the screenshot. Note I have already copied XSL files from wbem to sys32 dir
Can someone explain to me why these 2 commands that for me look exactly the same, with the only difference that one is executed outside wmic environment and the other one is from inside, the latter one doesn't work? I just fail to understand it.
Please advise so I can comprehend this a bit better! :-)
Try this
copy /y %WINDIR%\system32\wbem\en-US\*.xsl %WINDIR%\system32\
And then
wmic:root\cli>process list brief /format:htable.xsl > processlist.html
Note the presence of the extension after "htable"
You are attempting to use CMD.EXE > redirection while you are within the interactive WMIC context. That can't work.
You can use the WMIC /output:filename switch while in interactive mode. Each subsequent command will overwrite the output of the previous command. You can get multiple commands to go to the same file by using /append:filename instead. You can reset the output back to stdout using /output:stdout.
/output:processlist.html
process list brief /format:htable
/output:stdout
Did you try specifying a full path in the wmic:root\cli>process call? My bets are that the first worked because it output the file to the current directory.

Python not calling an external program part 3

I have been having problems trying to run an external program from a python program that was generated from a trigger in a postgres 9.2 database. The trigger works. It writes to a file. I had tried just running the external program but the permissions would not allow it to run. I was able to create a folder (using os.system(“mkdir”) ). The owner of the folder is NETWORK SERVICE.
I need to run a program called sdktest. When I try to run it no response happens so I think that means that the python program does not have enough permissions (with an owner of NETWORK SERVICE) to run it.
I have been having my program copy files that it needs into that directory so they would have the correct permissions and that has worked to some degree but the program that I need to run is the last one and it is not running because it does not have enough permissions.
My python program runs a C++ program called PG_QB_Connector which calls sdktest.
Is there any way I can change the owner of the process to be a “normal” owner? Is there a better way to do this? Basically I just need to have this C++ program have eniough perms to run correctly.
BTW, when I run the C++ program by hand, the line that runs the sdktest program runs correctly, however, when I run it from the postgres/python it does not do anything...
I have Windows 7, python 3.2. The other 2 questions that I asked about this are located here and here
The python program:
CREATE or replace FUNCTION scalesmyone (thename text)
RETURNS int
AS $$
a=5
f = open('C:\\JUNK\\frompython.txt','w')
f.write(thename)
f.close()
import os
os.system('"mkdir C:\\TEMPWITHOWNER"')
os.system('"mkdir C:\\TEMPWITHOWNER\\addcustomer"')
os.system('"copy C:\\JUNK\\junk.txt C:\\TEMPWITHOWNER\\addcustomer"')
os.system('"copy C:\\BATfiles\\junk6.txt C:\\TEMPWITHOWNER\\addcustomer"')
os.system('"copy C:\\BATfiles\\run_addcust.bat C:\\TEMPWITHOWNER\\addcustomer"')
os.system('"copy C:\\Workfiles\\PG_QB_Connector.exe C:\\TEMPWITHOWNER\\addcustomer"')
os.system('"copy C:\\Workfiles\\sdktest.exe C:\\TEMPWITHOWNER\\addcustomer"')
import subprocess
return_code = subprocess.call(["C:\\TEMPWITHOWNER\\addcustomer\\PG_QB_Connector.exe", '"hello"'])
$$ LANGUAGE plpython3u;
The C++ program that is called from the python program and calls sdktest.exe is below
command = "copy C:\\Workfiles\\AddCustomerFROMWEB.xml C:\\TEMPWITHOWNER\\addcustomer\\AddCustomerFROMWEB.xml";
system(command.c_str());
//everything except for the qb file is in my local folder
command = "C:\\TEMPWITHOWNER\\addcustomer\\sdktest.exe \"C:\\Users\\Public\\Documents\\Intuit\\QuickBooks\\Company Files\\Shain Software.qbw\" C:\\TEMPWITHOWNER\\addcustomer\\AddCustomerFROMWEB.xml C:\\TEMPWITHOWNER\\addcustomer\\outputfromsdktestofaddcust.xml";
system(command.c_str());
It sounds like you want to invoke a command-line program from within a PostgreSQL trigger or function.
A usually-better alternative is to have the trigger send a NOTIFY and have a process with a PostgreSQL connection LISTENing for notifications. When a notification comes in, the process can start your program. This is the approach I would recommend; it's a lot cleaner and it means your program doesn't have to run under PostgreSQL's user ID. See NOTIFY and LISTEN.
If you really need to run commands from inside Pg:
You can use PL/Pythonu with os.system or subprocess.check_call; PL/Perlu with system(); etc. All these can run commands from inside Pg if you need to. You can't invoke programs directly from PostgreSQL, you need to use one of the 'untrusted' (meaning fully privileged, not sandboxed) procedural languages to invoke external executables. PL/TCL can probably do it too.
Update:
Your Python code as shown above has several problems:
Using os.system in Python to copy files is just wrong. Use the shutil library: http://docs.python.org/3/library/shutil.html to copy files, and the simple os.mkdir command to create directories.
The double-layered quoting looks wrong; didn't you mean to quote only each argument not the whole command? You should be using subprocess.call instead of os.system anyway.
Your final subprocess.call invocation appears OK, but fails to check the error code so you'll never know if it went wrong; you should use subprocess.check_call instead.
The C++ code also appears to fail to check for errors from the system() invocations so you'll never know if the command it runs fails.
Like the Python code, copying files in C++ by using the copy shell command is generally wrong. Microsoft Windows provides the CopyFile function for this; equivalents or alternatives exist on other platforms and you can use portable-but-less-efficient stream copying too.

popen and system behaves unexpectedly with multiple quoted file paths

I am trying to execute a dos command from within my C++ program, however soon as I add quotes to the output filepath (of a redirection) the command no longer gets executed and returns instantly. I've shown an example below of a path without spaces, but since paths may have spaces and thus be quoted for the shell to understand it properly I need to solve this dilemma - and I'm trying to get the simplest case working first.
i.e.
The following WORKS:
sprintf(exec_cmd,"\"C:/MySQL Server 5.5/bin/mysqldump.exe\" -u%s -p%s %s > C:/backup.bak",user,password,db_name);
system(exec_cmd);
The following does NOT work (notice the quotes around the output):
sprintf(exec_cmd,"\"C:/MySQL Server 5.5/bin/mysqldump.exe\" -u%s -p%s %s > \"C:/backup.bak\"",user,password,db_name);
system(exec_cmd);
I'm guessing it is choking somewhere. I've tried the same "exec_cmd" in popen to no avail.
Any help/advice is greatly appreciated.
I don't think your shell (cmd.exe) allows redirection to a file name with spaces. I couldn't make my command.com from DOS 6.22 accept it (I don't have a cmd.exe nearby to test).
Anyway, you can use the --result-file option to pass the redirection to the command itself.
mysqldump ... --result-file="file name" ...