How to Profile a C-Program in a Loop of Shell Script, Using Shark on Mac? - macos

I have a question about Shark-profiling on mac.
Say if I have a C-program, compiled with:
gcc -o mycprog mycprog.c -g -pg
and also I have a shell script something like:
for file in ($SomeDirectory)
do
mycprog $file
done
I need to profile the average performance for all files in $SomeDirectory.
Where should I put the shark -i command? Thanks.

This is not a great approach, for various reasons - ideally you should modify your program's outer loop so that it can process all the files on the command line, then you can just do everything in one run:
$ shark -i
$ mycprog $SomeDirectory/*
If you can't do that then you will need to set your Shark configuration for system-wide profiling and start profiling before your bash loop and stop profiling afterwards. When you subsequently view the profile in Shark you'll be able to filter out the processes that you're not interested in.
Firstly open Shark (the GUI app), set up your configuration and enable remote control (Sampling => Programmatic). Make sure you have Time Profile and Everything selected.
Then from the command line:
$ chudRemoteCtrl -s "mycprog"
$ sleep 1
$ for f in $SomeDirectory/*
$ do
$ mycprog $SomeDirectory/$f
$ done
$ chudRemoteCtrl -e

Related

Run an alias based on output of another command

My laptop for option to switch fan speeds. So to change fan speed when it is plugged in, i want to write a alias to to detect if it is plugged in and check the fan speed accordingly.
To check if battery is plugged in, i have used command
acpi -a
which gives output of either off-line or online so based on this, i want to execute my alias.
Aliases I have created to switch fan speed is
alias fan-turbo='cd /sys/devices/platform/asus-nb-wmi; sudo sh -c "echo 1 >> fan_boost_mode"; sudo sh -c "echo 1 >> throttle_thermal_policy"; source ~/.bashrc;'
My approach was to get output and search for off-line using Grep, but don't know how to proceed.

Determining all the processes started with a given executable in Linux

I have this need to collect\log all the command lines that were used to start a process on my machine during the execution of a Perl script which happens to be a test automation script. This Perl script starts the executable in question (MySQL) multiple times with various command lines and I would like to inspect all of the command lines of those invocations. What would be the right way to do this? One possibility i see is run something like "ps -aux | grep mysqld | grep -v grep" in a loop in a shell script and capture the results in a file but then I would have to do some post processing on this and remove duplicates etc and I could possibly miss some process command lines because of timing issues. Is there a better way to achieve this.
Processing the ps output can always miss some processes. It will only capture the ones currently existing. The best way would be to modify the Perl script to log each command before or after it executes it.
If that's not an option, you can get the child pids of the perl script by running:
pgrep -P $pid -a
-a gives the full process command. $pid is the pid of the perl script. Then process just those.
You could use strace to log calls to execve.
$ strace -f -o strace.out -e execve perl -e 'system("echo hello")'
hello
$ egrep ' = 0$' strace.out
11232 execve("/usr/bin/perl", ["perl", "-e", "system(\"echo hello\")"], 0x7ffc6d8e3478 /* 55 vars */) = 0
11233 execve("/bin/echo", ["echo", "hello"], 0x55f388200cf0 /* 55 vars */) = 0
Note that strace.out will also show the failed execs (where execve returned -1), hence the egrep command to find the successful ones. A successful execve call does not return, but strace records it as if it returned 0.
Be aware that this is a relatively expensive solution because it is necessary to include the -f option (follow forks), as perl will be doing the exec call from forked subprocesses. This is applied recursively, so it means that your MySQL executable will itself run through strace. But for a one-off diagnostic test it might be acceptable.
Because of the need to use recursion, any exec calls done from your MySQL executable will also appear in the strace.out, and you will have to filter those out. But the PID is shown for all calls, and if you were to log also any fork or clone calls (i.e. strace -e execve,fork,clone), you would see both the parent and child PIDs, in the form <parent_pid> clone(......) = <child_pid> so then you should hopefully then have enough information to reconstruct the process tree and decide which processes you are interested in.

Lua Mac os.execute open Terminal and run command

I need to open the Mac Terminal and run some commands with os.execute in Lua
export VAMP_PATH=/path/to/plugin/directory
cd /path/to/script
./sonic-annotator -l
EDIT: got it to work without terminal with this
os.execute('export VAMP_PATH="'..script_path..'sonic/mac64/vamp"; cd "'..script_path..'sonic/mac64/"; ./sonic-annotator -d vamp:qm-vamp-plugins:qm-barbeattracker:beats -w csv "'..filename..'"')
To answer your actual question, you can start a Terminal and run some bash commands in it like this:
os.execute("osascript -e 'tell application \"Terminal\" to do script \"cd /Users/mark && ls\"'")
But, as I said in the comments, you don't necessarily need a Terminal to run a script, so you can just run a command like this:
os.execute("export V=fred; cd /Users/mark && ./SomeScript.sh")
If you are running a script because you just want the user to see the output of the script, it is often easier and involves far less quoting if you run your command and pipe the result to open -f like this, which displays the output in a text editor:
os.execute("cd /Users/mark; ls | open -f")

How to update filename with date in current time

I am trying to launch a stdbuf which be able to make a new log each day using this order in the shell:
stdbuf -i0 -o0 -e0 /.../my_dir/watchdog_foo >> /.../my_dir/log_foo_`date '+%F'` &
With this, I would want to have:
log_foo_2017-11-28
log_foo_2017-11-29
...
For testing, I have launched this other order:
stdbuf -i0 -o0 -e0 /.../my_dir/watchdog_foo >> /.../my_dir/log_foo_`date '+%R'` &
trying to see if a log was created each minute, but it didn't happened. The log had been writing on the same file all this time whileas what I hopped was:
log_foo_18:05
log_foo_18:06
...
How could I modify this command for achieve my purpose?
When you launch this command, the date +%R is expanded by your shell to the current time. After that, it is not updated again, so your log will be redirected to the same file. To get your desired behavior, you'd need to re-launch your script every day (to get the updated date). You could use a tool like cron to run the script every night at midnight to kill the previous process and re-run with the new date.
You could also look into leveraging a tool like logrotate.

bash script -> ps read nothing of a command launch within the script

I'd like to understand why when I execute the following command in my terminal it works, but when I run through a script it doesn't
the command when I run it in my terminal
./tparente & ps --no-headers -C tparente -o rss,vsz >> "mem_results"
The mem_result file has the rss and vsz written in it.
The command when I run it through my terminal is slightly modified, it is written like this:
sh ~/Documents/tparente & ps --no-headers -C tparente -o rss,vsz >> "mem_results"
There's an echo command that write some text in mem_results before the aforementioned command, those works.
And if I remove the no header flag, it writes the header in the file but not the result.
I know the script is run, because it produce a file at the end.
This has been bugging me for a couple hours now.
Thank you
Alex.
I think I may have found the answer.
After trying a couple of configuration of the command line: this one works:
./tparente & ps --no-headers -C tparente -o rss,vsz >> "mem_results"
The difference is subtle (there's no "sh")
This line is from the script; what I noticed is when I tried to run the script on it's and run a ps command in another terminal, the tparente process was is there. I don't know why, but my instinct told me to remove the sh and I did and it works.
If anyone has a proper explanation go ahead :)

Resources