how to perform automated Unix input? - linux

How can you set a string to be used instead of standard input? For example, when running the latex command in Unix it will always find some trivial errors, to skip through all errors you have to enter "r" into the command line (I now know that with latex specifically you can use -interactionmode nonstopmode, but is there a more general solution to do this?)
Is there anyway to specify that this should be done automatically? I tried redirecting standard input to read from a file containing "r\n", but this didn't work.
How can I achieve this?

Not all applications that need input can be satisfied with their stdin redirected.
This is because the app can call the isatty C function (if written in C, or some equivalent call for other languages) to determine if the input come from a tty or not.
In such situation, there is a valuable tool to use, and this is expect.

latex --interaction=MODE
where MODE is one of:
errorstopmode: stop at every error and ask for input
scrollmode: scroll over non-fatal errors, but stop at fatal errors (such as "file not found")
nonstopmode: scroll over non-fatal errors, abort at fatal errors
batchmode: like nonstopmode, but don't show messaes at the terminal
For interactive use, errorstopmode (the default) is fine, for non-interactive use, nonstopmode and batchmode are better.
But beware, there are no trivial errors: all errors must be fixed, and all warnings should be fixed if possible.
Redirecting stdin works without problems here:
/tmp $ tex '\undefined\end' <<< r
This is TeX, Version 3.1415926 (TeX Live 2010)
! Undefined control sequence.
<*> \undefined
\end
? OK, entering \nonstopmode...
(see the transcript file for additional information)
No pages of output.
Transcript written on texput.log.

You've got two plausible answers detailing the way to handle Latex specifically. One comment indicates that you need a more general answer.
Most usually, the tool recommended for the general solution is 'expect'. It arranges for the command to have a pseudo-tty connected for input and output, and the command interacts with the pseudo-tty just as it would your real terminal. You tell 'expect' to send certain strings and expect certain other strings, with conditional code and regular expressions to help you do so.
Expect is built using Tcl/Tk. There are alternative implementations for other languages; Perl has an Expect module, for example.

From the man page:
-interaction mode
Sets the interaction mode. The mode can be either batchmode, nonstopmode, scrollmode, and errorstopmode. The meaning of these modes is the same as that of the corresponding \commands.
Looks like -interaction nonstopmode might help you.

Related

How to call external "interactive/TUI" command, interact, and read std output

I am trying to write my first vim script, so I apologize if this question boils down to not understanding the basics.
The main goal is that I want to call out to an external command from inside vim and read the results back into the file.
I know how to do this with simple shell commands, e.g. r !ls. However the command I want to interact with is "interactive".
I don't know if this is a meaningful description. But calling this command in the shell opens a TUI, then after interacting with the TUI the command will exit and put things into standard output. I want to read that standard output back into vim.
Possibly it will help to discuss the specific command, which is papis a cli citation manager. If you call, e.g. papis list --format '{doc[title]} {doc[author]}' in the shell it will open up a TUI that allows me to filter down and select a document. After selecting the document it will put the title and author into the standard output. This is what I want to read into vim.
However, my first few attempts have not been successful. Trying the naive :r !papis list results in an error, even though that command is valid in the shell and would result in the TUI being opened. So I'm obviously missing something.
Can anyone recommend a guide or suggest a possible solution for correctly calling out to TUI-based external commands and reading back their standard output?

Is there a way to check whether an option is valid for a certain program?

For example, cat doesn't have an option '-a'
When I try to run cat -a, I get the error message and usage line. Can I somehow get a truth value instead?
or do I have to do something like:
MESS=$(cat -a)
ERROR='illegal option -- a
usage: cat [-benstuv] [file ...]'
if [ "$MESS" = "$ERROR" ] ; then
....
(although that doesn't work, it still prints the message to the screen instead of storing it to MESS)
you can see that certain program manual to see available options for ex.
man cat
Unix programs have a lot of flexibility in parsing command-line options, and the list of recognised options are not exposed in a machine-readable form. A perverse program could even vary its recognised options from run to run. At best, you are going to have to use heuristics based on parsing man pages and error output, but this is going to be quite error-prone.
However, all is not lost. The fish(1) shell has a lot of magic in it to guess likely-looking options for tab-completion, and you could inspect its code to see how it's done.

trick console prog to make it think it writes to terminal

Many terminal programs will behave differently depending on the STDOUT destination, either terminal or pipe or file. Usually they will remove colors. There are usually command line options for some of them to keep colors or formatting or anything else that is intended only for direct terminal output. But those options are not always present and it takes time to find them thus I need a generic way to trick the program so that it thinks that STDOUT is terminal, not a pipe. How to achieve this?
There are several tools for this, they basically create a pty for your command.
The best known is probably expect: http://expect.sf.net
Alternatively, empty: http://empty.sf.net
There are several examples in that page, have a look.
For simple cases, script -c 'mycommand' may be a viable alternative.
And tmux, which is powerful and pretty easy to script.

Go to beginning of output command created - shortcut

I can scroll trough bash output using shift+pgup/pgdown.
But lets say, some command outputted lot of text, I have to pageup few times to go to beginning of output of this command.
Can I just simply do this by some shortcut? Something that simply allows me to scroll between previous commands (not history!), seeing their output.
You could try piping the output into less:
someCommand | less
less will allow you to search and scroll through the output text pretty easily.
once in less you can just type % to jump back to the top of the page. Essentially that means jump to 0% of the page. There are also a bunch of extra commands on the page I linked to above.
Another option is to use screen and use backward search (beware: read the Overview first, especially the part about the C-a prefix) to e.g. search for some specific characters in your prompt (like your username).
The scroll back history in Unix shells is a shell specific functionality, meaning that it is up to the specific shell (xterm, rxvt, text console, etc) to handle it. The functionality you request would require the shell to identify the individual program runs, to know where to scroll to. Scanning text is not technically hard per se, but as prompts and command display can differ due to user settings it can be hard to make it work generally good. Some communication between the shell and the terminal could make it better.
There sure are some nice fancy terminal programs doing things like this, to for example show syntax help when writing commands, but for your case I agree with previous answer, that piping commands to less is a good way to isolate the output. It might be a bit cumbersome first, as it requires you to think about it first, and not just go back in history, but if you learn the shell better and learn to use the command history it will probably work fine. I recommend you to, if you haven't already. What I mean is ctrl-r etc. More described for example here:
http://www.catonmat.net/blog/the-definitive-guide-to-bash-command-line-history/

How do the Server Extensions work in X?

Let's take an example. When I run:
xkbprint $DISPLAY keyboard.ps
what happens in the system? I would like to know how the X really work because I regularly get nasty error reports such as
Fatal Error: Cannot load geometry for /tmp/launch-NawGIk/:0
Exiting
I know that the X11 was designed in a way that it is easy to extend. But how? How does the X11 protocol work? How do the X extensions work?
Whatever happens, I'm pretty certain it isn't going to be what you expect.
The syntax of xkbprint(1) is
$ xkbprint sourcefile destfile
and sourcefile should be a compiled xkb file. $DISPLAY is going to resolve to something like mymachine:0.0, which isn't a very reasonable file name.
Actually, since you're running a Mac, it's echoing exactly what it's seeing: /tmp/launch-NawGIk/:0 is the special OS/X magic to let launchd run X apps. The error message means that it's not finding a geometry or display in that file. Which is no surprise since there is no file named `/tmp/launch-NawGIk/:0
Try reading the man page, and see if you don't have more luck with a compiled .xkm file.
More generally, if you want a starting introduction to X, try this article.
Man xkbprint says:
The xkbprint comman generates a
printable or encapsulated PostScript
description of the XKB keyboard
description specified by source. The
source can be any compiled keymap
(.xkm) file that includes a geometry
description or an X display
specification.
As Charlie Martin pointed out, xkbprint is misusing your $DISPLAY as a file name. Try specifying the display more precisely, to avoid ambiguity with file name. Try man xhost. Maybe passing simple ":0" will fix the problem?

Resources