Execution time of a ksh script - bash

I want to know execution time of the ksh script, without editing or running the script.
any command to get time taken by the script to execute?

You can try time command as below ;
root#host:/tmp:>cat test.ksh
#!/bin/ksh
echo started
sleep 3
echo finished
root#host:/tmp:>date; time ksh test.ksh ; date
Tue Jul 19 14:36:43 EEST 2016
started
finished
real 0m3.006s
user 0m0.001s
sys 0m0.002s
Tue Jul 19 14:36:46 EEST 2016

Use the time command with your script:
time for x in 1 2 3 4; do ./your_script.ksh; done
real 1m20.085s
user 0m0.021s
sys 0m0.025s
or you can use the SECONDS parameter available in ksh within your script:
begin_time=$SECONDS
your_shell_code_here
end_time=$SECONDS
elapsed_time=$((end_time - begin_time))
Refer to printf to format the output contained in elapsed_time.

Related

Bash: Running a script that runs another script as a separate process

I have a script that does stuff with an ID as a parameter, I want to make it accept multiple parameters and then duplicate itself so that each copy runs with its own parameter from the list. For instance, I run "script 1 2 3&", and I want to see the result as if I were to run "script 1&", "script 2&", and "script 3&".
I can launch a script inside a script using
MyName="${0##*/}"
bash ./$MyName $id
$id is basically the parameter I want to put in this script. I launch multiple of them; however, the scripts I launch from within the script get processed in a raw, one after another, not parallel. I tried adding '$' at the end after $id, did not work.
Is it possible to launch a script from a script so that they run as separate processes in the background as if I were to run multiple scripts with & myself from the terminal?
This does what I think you want... with some dummy example code for the case of handling a single id.
If no parameters are given, it will give you Usage: output, if more than one parameter is given it will invoke itself as a background job, once for each of those parameters, and then wait for those background jobs to be finished.
If only one parameter is given, it will execute the workload for you.
A cleaner approach would probably be to do this in two scripts, one that is the launcher that handles the first two situations, and a second script that handles the work load.
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage $0 <id1> ..." 1>&2
exit 1
fi
if [ $# -gt 1 ]; then
# Fire up the background jobs
for myid in $*; do
$0 $myid &
done
# Now wait for the background scripts to finish
wait
exit 0
fi
id=$1
echo "PID $$ ($id) - Hello world, on $(date)."
sleep 5
Example run:
$ ./myscript.sh 10 20 30 40 50; date
PID 8558 (10) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
PID 8559 (20) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
PID 8560 (30) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
PID 8561 (40) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
PID 8563 (50) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
Tue Jun 21 22:22:15 PDT 2022
The ; date at the end shows that the initial script doesn't return until all child processes are finished.

How to store date, time, and the user's IP in Bash history

I need to re-setup history command to show both date, time and the IP address of user's from where they logged in to our server and execute a particular command. Is there any way to show these info with the history command?
The Sample Output would be:
Sat 04 Nov 2017 06:20:20 AM +03 111.111.111.111 : pwd
Sat 04 Nov 2017 06:20:20 AM +03 111.123.123.111 : mkdir test
Sat 04 Nov 2017 06:20:20 AM +03 123.123.44.32 : pwd
Help me to setup these changes via either .bash_profile or .bashrc
Though you can turn timestamps on in Bash history by setting HISTTIMEFORMAT, you cannot prefix a string to every line of the history file. You could use the DEBUG trap to achieve your goal, by maintaining your own history file:
save_history() {
# make sure IP is set in .bash_profile instead of capturing it each time here
printf '%s : %s : %s\n' "$(date)" "$IP" "$BASH_COMMAND" >> /path/to/history_file
}
trap save_history DEBUG
This way, the save_history function gets called before each command and it records the history in the file.
See also:
How to run some command before or after every Bash command entered from console?

script not running before sleep

I am trying to create a script that runs just before sleeping. Can someone tell me what I am doing wrong here? This script runs perfectly when I run the command in terminal.
king#death-star /etc/pm/sleep.d $ ls
total 1MB
drwxr-xr-x 2 root root 1MB May 30 15:21 .
drwxr-xr-x 5 root root 1MB Nov 28 2015 ..
-rwxr-xr-x 1 root root 1MB Jun 26 2015 10_grub-common
-rwxr-xr-x 1 root root 1MB Dec 6 2013 10_unattended-upgrades-hibernate
-rwxr-xr-x 1 root root 1MB May 22 2012 novatel_3g_suspend
-rwxr-xr-x 1 root root 1MB May 30 15:20 revert_kb_on_sleep
king#death-star /etc/pm/sleep.d $ cat revert_kb_on_sleep
sh -c "/home/king/Desktop/Scripts/rotate_desktop normal; /home/king/Desktop/Scripts/misc/my_keyboard on"
Output from log:
$ cat /var/log/pm-suspend.log
Running hook /etc/pm/sleep.d/revert_kb_on_sleep suspend suspend:
Can't open display
Can't open display
xrandr: --rotate requires an argument
Try 'xrandr --help' for more information.
No protocol specified
Unable to connect to X server
/etc/pm/sleep.d/revert_kb_on_sleep suspend suspend: success.
Mon May 30 15:23:39 EDT 2016: performing suspend
Mon May 30 15:27:59 EDT 2016: Awake.
Mon May 30 15:27:59 EDT 2016: Running hooks for resume
Running hook /etc/pm/sleep.d/revert_kb_on_sleep resume suspend:
Can't open display
Can't open display
xrandr: --rotate requires an argument
Try 'xrandr --help' for more information.
No protocol specified
Unable to connect to X server
/etc/pm/sleep.d/revert_kb_on_sleep resume suspend: Returned exit code 1.
Any luck with this? I wrote a script to run after waking, and I'm getting similar errors. This script is supposed to turn off the laptop display upon waking from sleep.
case "${1}" in
resume|thaw)
screen_status=$(xset -q -display :0.0 | tail -1 | sed 's/^[ \t]*//g')
if [[ "$screen_status" = "Monitor is On" ]]; then
sleep 1 && xset -display :0.0 dpms force off
fi
;;
esac
But I get the following error:
No protocol specified
xset: unable to open display ":0.0"
I've tried to get it to set screen_status as "Monitor is off" when it can't get a display, so that it triggers the condition to execute xset anyway, but that's not working, either, because it can't access the display. In the meantime, I set xfce4-power-manager to turn off the screen after 1 minute. Having to wait for a minute is better than nothing!

How to copy terminal content programmatically?

How can i read the content of a xterm or terminal, only by knowing its device number?
Similar to moving the mouse over the text.
Redirecting or cloning the terminal output to a file would be an option too, as long it could be done without interacting with commands executed in this terminal.
So nothing like 'command > myfile'.
Or is the only way to solve this a print screen with ocr or simulating mouse moves and clicks?
Edit: I m looking for a solution that reads the content regardless of his origin, p.e. 'echo "to tty" > /dev/pts/1'
The script command may work for you.
"Script makes a typescript of everything printed on your terminal. It is useful for students who need a hardcopy record of an interactive session as proof of an assignment, as the typescript file can be printed out later" - man script
You can even pass script as command when invoking xterm with -e:
ubuntu#ubuntu:~$ xterm -e script
ubuntu#ubuntu:~$ # A new xterm is started. uname is run, then exit
ubuntu#ubuntu:~$ # The output is captured to a file called typescript, by default:
ubuntu#ubuntu:~$ cat typescript
Script started on Tue 19 Nov 2013 06:00:07 PM PST
ubuntu#ubuntu:~$ uname
Linux
ubuntu#ubuntu:~$ exit
exit
Script done on Tue 19 Nov 2013 06:00:13 PM PST
ubuntu#ubuntu:~$

Using /usr/bin/time and redirecting the output into a file?

So I'm using /usr/bin/time to measure my program, and I'm doing multiple runs of the same program so I can gather results. The problem with doing multiple executions and using /usr/bin/time at the same time is that it'll print out that giant chunk of information multiple times, and I don't want to scroll, copy, and paste my results into a text file. I'd rather have the command line do it for me.
Originally, I thought the command was something like:
/usr/bin/time -v sudo ./programname >> timeoutput.txt
But as far as I know, >> is used for stdout, so it won't work in this case.
If you just want to append the standard error of time (which is the handle it uses for outputting the time information) to a file, you can use:
( time sleep 1 ) 2>>timeoutput.txt
The 2>>... bit redirects standard error rather than standard output and the () ensures that the redirection applies to time rather than the command you're running.
Of course, that won't stop any error output from the program you're timing from showing up in the file, if you want to guarantee that, you need something like:
( time ( sleep 1 2>/dev/null ) ) 2>>timeoutput.txt
This will ensure that no error output from the command trickles out to interfere with the error output of time.
In the above examples, I've used sleep 1 for the command but you should just replace that with whatever command you're trying to run.
Actually, time and /usr/bin/time may well be different. Some shells have a built in time function, note as follows from my ksh on Red Hat:
/usr/bin/time date
Thu Oct 31 12:57:04 EDT 2013
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 2864maxresident)k
0inputs+0outputs (0major+227minor)pagefaults 0swaps
time date
Thu Oct 31 12:57:11 EDT 2013
real 0m0.00s
user 0m0.00s
sys 0m0.00s

Resources