I want to use something like shell-out [ http://richhickey.github.com/clojure-contrib/shell-out-api.html ], but without capturing the any output. Of course the output can be passed to print, but this is slightly less than desirable (e.g. in the case that the subprocess may fail).
edit
Sorry, I want the subprocess to output to the same stdout as the parent process.
Also see this third party library
https://github.com/Raynes/conch
It provides direct access to the streams.
EDIT: Before Clarification
You can wrap the shell command with a sh and then pipe to /dev/null like so:
(clojure.java.shell/sh "sh" "-c" "echo hello > /dev/null")
;; {:exit 0, :out "", :err ""}
This will silence the output before getting to clojure.
EDIT: After Clarification
Passing output and stderr to print should work as long as the output comes out quickly enough. If you want something with continuous output of error messages and standard output, looking at the source for the "sh" function should help.
Personally, I would make my own version of clojure.java.shell/sh and for each stream, create a thread that pipes the output directly to out using something like IOUtils.copy from org.apache.commons.io.IOUtilsin
Related
I have written a script that I would like to take input either from a pipe or by providing a filename as an argument. ARGF makes it easy to deal with this flexibly, except in the incorrect usage cases where neither is provided, in which case STDIN is opened and it hangs until the user inputs something on the console.
I would like to catch this incorrect usage to display an error message and exit the program, but I haven't been able found a way. ARGF.eof? seemed like a possible candidate, but it also hangs until some input is received.
Is there a simple way for Ruby to discriminate between STDIN provided by a pipe and one from the console?
you can use
$stdin.tty?
for example
$ ruby -e 'puts $stdin.tty?'
> true
$ echo "hello" | ruby -e 'puts $stdin.tty?'
> false
I'm using a script which is calling another, like this :
# stuff...
OUT="$(./scriptB)"
# do stuff with the variable OUT
Basically, the scriptB script displays text in multiple time. Ie : it displays a line, 2s late another, 3s later another and so on.
With the snippet i use, i only get the first output of my command, i miss a lot.
How can i get the whole output, by capturing stdout for a given time ? Something like :
begin capture
./scriptB
stop capture
I don't mind if the output is not shown on screen.
Thanks.
If I understand your question, then I believe you can use the tee command, like
./scriptB | tee $HOME/scriptB.log
It will display the stdout from scriptB and write stdout to the log file at the same time.
Some of your output seems to be coming on the STDERR stream. So we have to redirect that as needed. As in my comment, you can do
{ ./scriptB ; } > /tmp/scriptB.log 2>&1
Which can almost certainly be reduced to
./scriptB > /tmp/scriptB.log 2>&1
And in newer versions of bash, can further be reduced to
./scriptB >& /tmp/scriptB.log
AND finally, as your original question involved storing the output to a variable, you can do
OUT=$(./scriptB > /tmp/scriptB.log 2>&1)
The notation 2>&1 says, take the file descriptor 2 of this process (STDERR) and tie it (&) into the file descriptor 1 of the process (STDOUT).
The alternate notation provided ( ... >& file) is a shorthand for the 2>&1.
Personally, I'd recommend using the 2>&1 syntax, as this is understood by all Bourne derived shells (not [t]csh).
As an aside, all processes by default have 3 file descriptors created when the process is created, 0=STDIN, 1=STDOUT, 2=STDERR. Manipulation of those streams is usually as simple as illustrated here. More advanced (rare) manipulations are possible. Post a separate question if you need to know more.
IHTH
I'm using a bash script to automatically run a simulation program. This program periodically prints the current status of the simulation in the console, like "Iteration step 42 ended normally".
Is it possible to abort the script, if the console output is something like "warning: parameter xyz outside range of validity"?
And what can I do, if the console output is piped to a text file?
Sorry if this sounds stupid, I'm new to this :-)
Thanks in advance
This isn't an ideal job for Bash. However, you can certainly capture and test STDOUT inside a Bash iteration loop using an admixture of conditionals, grep-like tools, and command substitution.
On the other hand, if Bash isn't doing the looping (e.g. it's just waiting for an external command to finish) then you need to use something like expect. Expect is purpose-built to monitor output streams for regular expressions, and perform branching based on expression matches.
How easy is it to hide results from system commands in ruby? For example, some of my scripts run
system "curl ..."
and I would not prefer to see the results of the download.
To keep it working with system without modifying your command:
system('curl ...', :err => File::NULL)
Source
You can use the more sophisticated popen3 to have control over STDIN, STDOUT and STDERR separately if you like:
Open3.popen3("curl...") do |stdin, stdout, stderr, thread|
# ...
end
If you want to silence certain streams you can ignore them, or if it's important to redirect or interpret that output, you still have that available.
Easiest ways other than popen:
Use %x instead of system. It will automatically pipe
rval = %x{curl ...} #rval will contain the output instead of function return value
Manually pipe to /dev/null. Working in UNIX like system, not Windows
system "curl ... > /dev/null"
The simplest one is to redirect stdout :)
system "curl ... 1>/dev/null"
# same as
`curl ... 1>/dev/null`
echo "yes\yes\oops" | program doesn't work well for a long-running program.
I can think of redirect the output of program to a file, then use a loop to grep that file until certain output appears. But is there any better idea?
If you prefer/are stuck with bash, perhaps you are looking for expect?
More on that here: http://wiki.tcl.tk/11583
Write a Python, Perl, Ruby or script in another language to interact with the program. In Python you'd use subprocess. In Perl you'd use popen(). Read the program's stdout line-by-line and match against known prompts, replying with the desired response by writing to the program's stdin.
You can do the same in bash, but I personally prefer not to.