Redirecting the output of program which itself is an argument - linux

Let me present the scenario first with the command which is not working under linux bash environment.
$ timed-run prog1 1>/dev/null 2>out.tmp
Here in the above case I want to redirect the output of program 'prog1' to /dev/null and out.tmp file. But this command is redirecting the output (if any) of timed-run to out.tmp.
Any help will be appreciated.

From a simple example, I experience exactly the opposite.
$ time ls 1> foo 2> bar
real 0m0.002s
user 0m0.004s
sys 0m0.000s
$ more foo
<show files>
$ more bar
<empty>
$
The output of ls is redirected, and the output of time is not!

The problem here is in timed-run not in bash. If you run the same command replacing timed-run with the standard time command this works as you expect. Mainly timed run needs to run the arguments of prog1 through the shell again. If it is a shell script you can do this with the eval command. For example:
#!/bin/sh
echo here is some output
echo $*
eval $*
now run
timed-run prog1 '1>/dev/null' '2>output.tmp'

How about using sh -c 'cmd' like so:
time -p sh -c 'ls -l xcvb 1>/dev/null 2>out.tmp'
time -p sh -c 'exec 0</dev/null 1>/dev/null 2>out.tmp; ls -l xcvb'
# in out.tmp:
# ls: xcvb: No such file or directory

Related

command to redirect output to console and to a file at the same time works fine in bash. But how do i make it work in korn shell(ksh)

command to redirect output to console and to a file at the same time works fine in bash. But how do i make it work in korn shell(ksh).
All my scripts runs on korn shell so cant change them to bash for this particular command to work.
exec > >(tee -a $LOGFILE) 2>&1
In the code beneath I use the variable logfile, lowercase is better.
You can try something like
touch "${logfile}"
tail -f "${logfile}"&
tailpid=$!
trap 'kill -9 ${tailpid}' EXIT INT TERM
exec 1>"${logfile}" 2>&1
A not too unreasonable technique is to re-exec the shell with output to tee. That is, at the top of the script, do something like:
#!/bin/sh
test -z "$REXEC" && { REXEC=1 exec "$0" "$#" | tee -a $LOGFILE; exit; }

Determine command line arguments a program uses to launch another one?

Motivation: When I run grub-mkrescue, it internally launches xorriso to write an iso file. I want to see what command line arguments xorriso is being passed. I know I could check the sources of grub-mkrescue, but I'm interested in a generic solution now. I tried with strace but the output didn't tell.
strace grub-mkrescue -o foo.iso iso/
Is there a way to do this?
A process will fork before running execve, so it will not show up in the strace of the parent.
Use strace -f to also follow children.
You can replace xorriso with a more verbose one:
which xorisso
cd $(dirname $(which ps))
mv xorisso xorisso.org
test -f xorisso | echo "mv failed, stop here"
cat <<'#' > xorisso
echo "$0 $#" > /tmp/xorisso_call.tmp
"$0.org" "$#"
#
chmod +x xorisso

What kind of command is "sudo", "su", or "torify"

I know what they do. I was just wondering what kind of command are they. How can you make one using shell scripting.
For example, command like:
ignoreError ls /Home/
ignoreError mkdir /Home/
ignoreError cat
ignoreError randomcommand
Hope you get the idea
The way to do it in a shell script is with the "$#" construct.
"$#" expands to a quoted list of all of the arguments you passed to your shell script. $1 would be the command you want your shell script to run, and $2 $3 etc are the arguments to that command.
The only example I have is from cygwin. Cygwin does not have sudo, but I have this script that emulates it:
#!/usr/bin/bash
cygstart --action=runas "$#"
So when I run a command like
$ sudo ls -l
my sudo script does whatever it needs to do (cygstart --action=runas) and calls the ls command with the -l argument.
Try this script:
#!/bin/sh
"$#"
Call it, for example, run, make it runnable chmod u+x run, and try it:
$ run ls -l #or ./run ls -l
...
output of ls
...
The idea is that the script takes the parameters specified on the command line and use them as a (sub)command... Modify the script this way:
#!/bin/sh
echo "Trying to run $*"
"$#"
and you will see.

Option -l of exec shell command

Could you please clarify on the use of -l option of exec shell command. I didn't notice any difference when I ran exec ls | cat and exec -l ls | cat.
The -l option of exec adds a - at the beginning of the name of your command. For example:
exec -l diff | head
-diff: missing operand after '-diff'
-diff: Try '-diff --help' for more information.
Note the - everywhere before diff.
The point of all this? If you have a - before a command to start a shell it will act as a login shell. From man bash:
A login shell is one whose first character of argument zero is a -, or one started with the --login option.
Now, man exec states that:
If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is
what login(1) does.
So exec -l bash will run bash as a login shell. To test this, we can use the fact that a login bash executes the file ~/.bash_profile, so:
$ cat ~/.bash_profile
#!/bin/sh
printf "I am a login shell!\n"
If I start a login bash, the command printf "I am a login shell!\n" will be executed. Now to test with exec:
$ exec bash
$
Nothing is displayed, we are on a non-login shell.
$ exec -l bash
I am a login shell!
$
Here we have a login shell.

how to redirect result of linux time command to some file

I'm running the following command (on Ubuntu)
time wget 'http://localhost:8080/upLoading.jsp' --timeout=0
and get a result in the command line
real 0m0.042s
user 0m0.000s
sys 0m0.000s
I've tried the following:
time -a o.txt wget 'http://localhost:8080/upLoading.jsp' --timeout=0
and get the following error
-a: command not found
I want to get the result to be redirected to some file. How can I do that?
-a is only understood by the time binary (/usr/bin/time), When just using time you're using the bash built-in version which does not process the -a option, and hence tries to run it as a command.
/usr/bin/time -o foo.txt -a wget 'http://localhost:8080/upLoading.jsp' --timeout=0
Checking man time, I guess what you need is
time -o o.txt -a ...
(Note you need both -a and -o).
[EDIT:] If you are in bash, you must also take care to write
/usr/bin/time
(check manpage for explanation)
You can direct the stdout output of any commmand to a file using the > character.
To append the output to a file use >>
Note that unless done explicitly, output to stderr will still go to the console. To direct both stderr and stdout to the same output stream use
command 2>&1 outfile.txt (with bash)
or
command >& outfile.txt (with t/csh)
If you are working with bash All about redirection will give you more details and control about redirection.
\time 2> time.out.text command
\time -o time.out.text command
This answer based on earlier comments. It is tested it works. The advantage of the \ over /usr/bin/ is that you don't have to know the install directory of time.
These answers also only capture the time, not other output.
Exactly the time from GNU writes it's output to stderr and if you want to redirect it to file, you can use --output=PATH parameter of time
See this http://unixhelp.ed.ac.uk/CGI/man-cgi?time
And if you want to redirect stdout to some file, you can use > filename to create file and fill it or >> filename to append to some file after the initial command.
If you want to redirect stderr by yourself, you can use $ command >&2 your_stderr_output
Try to use /usr/bin/time since many shells have their own implementation of time which may or may not support the same flags as /usr/bin/time
so change your command to
/usr/bin/time -a -o foo.txt wget ....
How about your LANG ?
$ time -ao o.txt echo 1
bash: -ao: コマンドが見つかりません
real 0m0.001s
user 0m0.000s
sys 0m0.000s
$ export|grep LANG
declare -x LANG="ja_JP.utf8"
$ LANG=C time -ao o.txt echo 1
1
$ cat o.txt
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 1984maxresident)k
0inputs+0outputs (0major+158minor)pagefaults 0swaps
Try:
command 2> log.txt
and the real-time output from "command" can be seen in another console window with:
tail -f log.txt
This worked for me:
( time command ) |& tee output.txt
https://unix.stackexchange.com/questions/115980/how-can-i-redirect-time-output-and-command-output-to-the-same-pipe
You can do that with > if you want to redirect the output.
For example:
time wget 'http://localhost:8080/upLoading.jsp' --timeout=0 > output.txt 2>&1
2>&1 says to redirect STDERR to the same file.
This command will erase any output.txt files and creates a new one with your output. If you use >> it will append the output at the end of any existing output.txt file. If it doesn't exist, it will create it.

Resources