It's common to use the command more. more is usually used with pipe. so I think more has the ability to read from stdin. every command separated by pipe is a process, and the one before more just create pipe and dup2 the write pipe to more's stdin. but I found that if I type "more" in the console, just some usages appear. so what is the matter?
Why do you think that anything is wrong? More pages output for the terminal so what would be the point in waiting for enough typed stdin input to page?
If you type more and one or more filenames it will page that input. So the behavior is something like:
am I attached to a terminal? ("isatty")
are there filenames in argv
page files
else
display help
else
page pipe input
It's a feature. It detects that its standard input is connected to a terminal, and displays a help message instead of proceeding. There is hardly a situation where it makes sense to run a pager on input while you are typing it in by hand. If you really actually want to, try cat | more for example.
For what's worth, I looked at the source package provided by the repositories in my linux distribution and found this:
if (!no_intty && nfiles == 0) {
usage(argv[0]);
exit(1);
}
So indeed the behaviour is to display the usage message if no input is detected.
Related
I've pushed a couple of process to background and redirected the output to /dev/null. I want undo that and see what's happening since its been in the background for a long time.
Is there a way to undo the > /dev/null redirection and bring the process to foreground?
I think you question would be better posted on unix.
There, you can find How to change the output redirection of a running process?, which exactly your question casted in a more general form.
From the answers, and from the 3rd party tool (redirect) suggested in the accepted answer by its creator, which is mostly written in C, I deduce that there's no shell-only way to accomplish what you want.
However that question is from 2012, so you might want to ask a new one to see if something changed in the meanwhile.
Last but not least, doing some search in man bash I've found the Coprocesses section, that reads
[…] A coprocess is executed asynchronously in a subshell, as if the command had been
terminated with the & control operator, with a two-way pipe established between
the executing shell and the coprocess. […] The standard output of command is
connected via a pipe to a file descriptor in the executing shell, and that
file descriptor is assigned to NAME[0]. The standard input […]
which is probably a way to launch processes in background without losing the ability to change their file descriptors, if I interpret the quote correctly.
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.
I am using the subprocess module like that:
ping = subprocess.Popen('fping.exe 192.168.2.3 196.65.58.69', stdout=PIPE)
output = ping.stdout.readlines()
I am need the output list in order to process it later at the program, but it seems since the stdout is directed to PIPE it isn't output the results to the console. I would like to get both the console output (as it being executed) and the output list.
How can i do that ?
I have done a search, and got an answer here, but i am unable to implement it.
I am using Python 3.x on Windows env.
Thanks.
There's no such thing as a pipe that goes to two places. Everything written to a pipe will only be read once. (While it's theoretically possible for your program and the console to have access to the same out pipe, if you succeed in doing so then only some of the data will go to your program, and only the data that doesn't will end up on the console.) To get all the output to your program and to the console, someone will have to read and duplicate the data. On a unix-like system, you might use the "tee" command for this, but you probably don't have that on your Windows machine.
So you will have to write the output to the console as you get it.
In this case, you can probably get away with using readline() in a loop instead of readlines().
I have found a way to do that here is it:
for line in os.popen("Fping x.x.x.x x.x.x.x -l"):
ipList.append(line)
print(line)
That way, i am able to get the results from the Fping program into the list, and to print it to the screen while it is executing, since the for loop with the os.popen aren't wait for the program to finish, but always looping at every line from the program.
I am developing a Qt application in Linux. I wanted to pass Linux commands to a terminal. That worked but now i also want to get a response from the terminal for this specific command.
For example,
ls -a
As you know this command lists the directories and files of the current working directory. I now want to pass the returned values from the ls call to my application. What is a correct way to do this?
QProcess is the qt class that will let you spawn a process and read the result. There's an example of usage for reading the result of a command on that page.
popen() , api of linux systerm , return FILE * that you can read it like a file descriptor, may help youp erhaps。
Parsing ls(1) output is dangerous -- make a few files with funny names in a directory and test it out:
touch "one file"
touch "`printf "\x0a\x0a\x0ahello\x0a world"`"
That creates two files in the current working directory. I expect your attempts to parse ls(1) output won't work. This might be alright if you're showing the results to a human, (though a human will be immensely confused if a filename includes output that looks just like ls(1) output!) but if you're trying to present something like an explorer.exe or Finder.app representation of files in the filesystem, this is horribly broken.
Instead, use opendir(3), readdir(3), and closedir(3) to read directory entries yourself. This will be safer, more portable, and (as a side benefit) slightly better performing.
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.