Preventing a Ghostscript command from entering the Ghostscript command line interface after execution - ghostscript

Whenever I execute a Ghostscript command, like the one below, in the Windows command line window, upon completion it automatically enters into the Ghostscript command line interface (GS >, as shown in the screenshot below). I wonder if there is a way to prevent ghostscript from doing it.
EDIT:
Realized that the dNoCancel flag should be removed. Once it's removed, it no longer enters the gs command line interface.

What happens is that the interpreter starts up and, if any actions have been specified on the command line those are executed as part of initialisation. This includes running any files. Then the interpreter returns to the interactive prompt awaiting further input.
There is plenty of documentation available for Ghostscript (possibly too much). If you go here then the switches relating to interaction with the user are described.

Related

Confusion about using shell pipes from vim command mode

I have a function (written below; source: TeX SX) that uses pipes in the shell which I'd like to use in vim command mode. It works as intended from the shell but returns an E34: No previous command error if entered in vim command mode. Full credit goes to jirislav in this post on TeX SX.
: | pdflatex -halt-on-error src.tex | grep '^!.*' -A200 --color=always
I'd very much like to have this shell functionality from the vim command line if anyone can help with that.
I tried the following from within vim command mode:
:! : | pdflatex -halt-on-error src.tex | grep '^!.*' -A200 --color=always
returns the E34 error. No pipes hides all compilation; however, it also doesn't output errors. Deleting 1 of 2 of the pipes also returns E34 errors for me.
I tried further troubleshooting to no success and here are some results of that. The help for :! says
a pipe '|' in {cmd} is passed to the shell, you cannot use it to append a vim command. See :bar
and :bar says (something that's referred to as escaping it out I think)
'|' can be used to separate commands, so you can give multiple commands in one line. If you want to use '|' in an argument, precede it with '\'.
I tried doing what :bar suggests, i.e.
:! : \| pdflatex -halt-on-error src.tex \| grep '^!.*' -A200 --color=always
The result is it hides everything, including compilation errors that I want to see. So I've come to the conclusion that I have no clue how to properly use shell pipes in vim command mode.
If you aren't a LaTeX user, all that the function is meant to do is the following. pdflatex compiles what's going on in vim into a pdf file. Enacting :! pdflatex % from vim's command mode outputs a whole slew of processing text and interrupts workflow; the grep in the function yanks out compilation errors, if they exist. The function, then, is meant to hide all output from pdflatex unless a compilation error occurs, in which case it outputs only the error and outputs it in red.
If anyone cared to explain the E34 error and why it doesn't work that would be appreciated, also.
Edit 1: This is now solved thanks to filbranden. Below there are a couple pictures attached of a minimal example should anyone come across this later.
vim file before input, output
Edit 2: Should you want to stick this in your .vimrc file, you'll need to escape out the pipe before grep, else the vimrc file defaults to thinking that pipe is a separator.
E34: No previous command
So the answer to your question was hiding in plain sight under :help E34, which redirects to the :! command.
(Vim pro-tip: whenever you get an error from Vim, ask for :help on the error code to get more context about it.)
The section on :! includes this passage:
Any ! in {cmd} is replaced with the previous external command. But not when there is a backslash before the '!', then that backslash is removed.
You did have a ! in your command, as part of the grep regular expression, ^!.*, so that was triggering the "history" behavior, trying to replace with the previously executed command. But since no command had executed at that point, the command failed with an error.
You can solve it by escaping the ! with a backslash, which Vim will remove before passing the command to the shell:
:! pdflatex -halt-on-error src.tex | grep '^\!.*' -A200 --color=always
But note that there are better ways to approach this problem! Let me cover some of them.
Using systemlist()
One great way to run external commands in Vim is to use the systemlist() function, which runs the command on a shell, captures its output, splits it into lines and returns a List with the resulting output lines.
So you could start with:
let latex_output = systemlist('pdflatex -halt-on-error src.tex')
And then use Vimscript commands to check for lines starting with ! to report to the user.
Note that, unlike with :!, the output of systemlist() is never displayed to the user (which means you don't switch back to seeing a terminal, possibly a blank one, and after the execution you don't have a "Hit enter prompt.) Which is great!
But that means you need to present that information to the user, when there are errors. A great way to do that is to use the quickfix window!
You can use the setqflist() function to set the contents of the quickfix window.
(For best results, you should set 'errorformat' appropriately, more on that later.)
Using vim-dispatch
If you don't like the part of running an external command (either through :! or systemlist()) that has it block Vim until the command execution is completed, then consider installing the vim-dispatch plug-in.
It can execute a command for you in background or in a separate terminal, so you're not blocked from editing. It also integrates with the :make command and the quickfix window.
Compiler configuration in vim-latex
Finally, the vim-latex plug-in (also known as latex-suite) has configurations to help you run pdflatex and report errors.
It includes a Vim :compiler configuration that will run pdflatex for you as a :make program. It also will set 'errorformat' to recognize the ! LaTeX Error string and recognize the line number of the errors, so you can jump to them directly from the quickfix list.
Note that vim-latex also has many other features to help you write LaTeX documents in Vim (besides managing the output generation through the compiler support.) You might want to check these other features as well.
(Since the plug-in has quite many features, I recommend reading the whole documentation to get you started on it.)
Also note that this plug-in is compatible with vim-dispatch (since vim-latex provides a compiler interface and vim-dispatch consumes it), so you can use both together if you like them both!

Is it possible to obtain the _raw_/_unprocessed_ command line?

The windows API provides GetCommandLine() which returns the cooked command line used to start a process.
For instance, if a console application is started with the command:
MyProg.exe > OutputHere
The command line seen by MyProg.exe will not include the portion
> OutputHere
I'd like to somehow get the command line exactly as it was. Is this possible ? and if yes, how ?
Suggestions in C and/or plain (no objects) Delphi greatly appreciated. Creative solutions welcome (hopefully, not requiring ring 0 code.)
Thank you very much for your help.
NOTE: I can tell if the input/output, etc has been redirected but, that is not what I'm looking for. I need the original/uncooked command line.
The redirection or piping of stdin, stdout and stderr is handled the command interpreter, typically cmd.exe. The interpreter parses the command and creates the necessary files and pipes, and then creates the one or more processes needed to implement your command.
The processes that are created have no knowledge of the original command, they only get that part of the command that is not related to piping and redirection.
So what you are trying to do is not possible, at least within your process. The only thing that knows the original command is the command interpreter.
Whether or not you can retrieve the full command line including the pipe commands depends on whether your start the program in a command window or for example using the "Run" command from the Start menu. If you use the "Run" command from the Start menu GetCommandLine actually retrieves the full command line including the redirection commands, but redirection does not work as it seems to be a feature of CMD.EXE.
As others have pointed out, what are you trying to achieve here / why do you need to capture the redirection commands?

what is EOF in cygwin in windows 10

I used to run cygwin on win8.1, and while giving inputs to a program CTRL-Z used to denote EOF. Today I installed cygwin on win10, and ran "a.out". After typing in the input data, when I press CTRL-Z I get the message "Suspended" and I get back the shell prompt. I tried this with bash and csh, same result. CTRL-D also does not work, it is killing the shell.
Just to confirm that it is only this problem and nothing else, I created a new input.txt file, and entered the relevant input data in it, and ran "a.out < input.txt", and it worked fine. So the problem is only in defining EOF for STDIN.
How to solve this problem?
Note: I am closing this question, and put in more details in a new question reading till EOF in java on cygwin on windows-10
On Unix-like systems, including Cygwin, Ctrl-D is (by default) configured to trigger an end-of-file condition when reading from a tty (terminal/keyboard). It's possible to change this using the stty command, but it looks like you haven't done that (and you almost certainly shouldn't).
If you enter Ctrl-D while running your program that reads from standard input, that will likely terminate your program, depending on how it responds to reaching the end of its input.
Ctrl-Z sends a signal that suspends your current program (some programs, such as interactive shells, are able to handle or ignore that signal). (Windows uses Ctrl-Z to trigger end-of-file.)
The behavior you describe indicates that you're typing Ctrl-D at a shell prompt. This gives the shell, not your program, and end-of-file condition. The shell response to this by terminating (by default; you can use set -o ignoreeof to tell the shell to ignore it).
If you type Ctrl-D while running your program, it should correctly trigger and end-of-file condition and cause your program to terminate.
UPDATE: Normally you should type Ctrl-D either before any other input (resulting in the program receiving no input at all), or immediately after typing Return. To trigger end-of-file in the middle of a line, you'd have to type Ctrl-D twice. (This is usually not a great idea, since it results in the program seeing a partial line with no terminating newline character.)

When data is piped from one program via | is there a way to detect what that program was from the second program?

Say you have a shell command like
cat file1 | ./my_script
Is there any way from inside the 'my_script' command to detect the command run first as the pipe input (in the above example cat file1)?
I've been digging into it and so far I've not found any possibilities.
I've been unable to find any environment variables set in the process space of the second command recording the full command line, the command data the my_script commands sees (via /proc etc) is just _./my_script_ and doesn't include any information about it being run as part of a pipe. Checking the process list from inside the second command even doesn't seem to provide any data since the first process seems to exit before the second starts.
The best information I've been able to find suggests in bash in some cases you can get the exit codes of processes in the pipe via PIPESTATUS, unfortunately nothing similar seems to be present for the name of commands/files in the pipe. My research seems to be saying it's impossible to do in a generic manner (I can't control how people decide to run my_script so I can't force 3rd party pipe replacement tools to be used over build in shell pipes) but it just at the same time doesn't seem like it should be impossible since the shell has the full command line present as the command is run.
(update adding in later information following on from comments below)
I am on Linux.
I've investigated the /proc/$$/fd data and it almost does the job. If the first command doesn't exit for several seconds while piping data to the second command can you read /proc/$$/fd/0 to see the value pipe:[PIPEID] that it symlinks to. That can then be used to search through the rest of the /proc//fd/ data for other running processes to find another process with a pipe open using the same PIPEID which gives you the first process pid.
However in most real world tests I've done of piping you can't trust that the first command will stay running long enough for the second one to have time to locate it's pipe fd in /proc before it exits (which removes the proc data preventing it being read). So if this method will return any information is something I can't rely on.

Redirecting cmd stdout and stderr back to parent

If I create a process from a cmd prompt using the start command (opening a new cmd) is it possible to redirect the stdout and stderr from that process back to the calling cmd?
If you want the output of the STARTed process to appear in the parent command console, then simply use the START /B option.
If you want to process the output of your command, then you should use FOR /F ... in ('someCommand') DO ... instead.
OK. I have yet to find a straightforward answer to this question. I didn't want to bog down my question with what I thought unnecessary detail but seeing as I'm being criticized for the lack of this I'll expand a bit here.
I want to automate the updating of FWs on our production line, so I've a python app that gets the FWs from ftp and then uses the processors flash tool via python subprocess command to upload it to the board's flash. OK for all but one of the tools.
The one tool seems to have a problem when it's not running in its own terminal, so I provide a start to the subprocess command string which allows it to run OK in its own terminal. However, I need the output from this other terminal for logging reasons.
A possible solution was to log stdout and stderr to file using >> or wintee and then poll this file via a thread in my original app (perhaps a rather convoluted solution to the question). However the tool also has a separate problem where it doesn't like any std redirection, so this doesn't work for me.

Resources