Check which processes are running from a given location in bash - linux

I have the following directories structure:
./folder1
-- file1.py
-- file2.py
./folder2
-- file3.py
-- file4.py
etc...
useless_file_a.py
useless_file_b.py
I am trying to write a bash script to know which of file[i].py processes are running. By running, I mean to see the process displayed as a result of the ps -elf command.
My idea is to:
Loop through those folder[i] and list the .py files available. For this step I can use:
find . -type f -name "*.py" -mindepth 2
Check running processes that matches the names found in 1.
I know about the ps -elf command and I would like to link it to step 1.
I am struggling to come up with something for this last step.
The whole point of this script is to alert me if one of those .py scripts are not running. As there can be many scripts and many folders, I want to automatize this process.
NB: The useless_file_*.py are in the pwd and are not relevant for me.

It's not possible, generally, to find out "if a script is running". This information is not stored anywhere.
You can check if the string that is the filename is in the command line arguments of processes:
for f in */*.py; do
pgrep -f "$(basename "$f")"
done

Related

Running script on output files

I am trying to run script on output files that can be further used as input files for gaussian.
I wanted to know what are the commands used in Linux to run the script on .log files and .HSCP1 files.
Many thanks,
Regards,
The generic syntax of passing an argument to a script in linux, assuming your script is named script.sh and your target file is named arg.log, would be
script.sh arg.log
This assigns the name arg.log to $1 inside the environment of the executing copy of script.sh. If you don't then do something with that, it won't matter.
You might also have your script read its stdin like this:
script.sh < arg.log
which will put the contents os arg.log on script.sh's stdin, but unless it reads them accordingly, it won't matter.
Of course, both these assume script.sh is in your $PATH; otherwise you will need to apply a path for the OS, such as /path/to/dir/with/script.sh or (if you are in the same directory) ./script.sh.
If what you are asking is how to get a lorge number of files assigned as arguments, you could pass wildcards - for the first example above, that could be done as
./script.sh /path/to/*.log /also/to/other.*
or you could use find, maybe with xargs like so -
find /path/to/files/ -name *.log | xargs /path/of/script.sh
which will call the script over and over.
I hope one of these helps, but you really must provide more context for what you are doing and how.

Is a script called somewhere

On one of my linux servers I have a script that performs some controls.
Is there a way of finding out where this script is called? This can be in
another script, cobol program, crontab, ...
Opening every one of them will take a very long time.
If you can modify the script, put in a ps line to get the parent pid, ps again and grep for the parent pid to get the command, then log to file.
Come back in a week or so and you should have the command that is triggering your script. In case it's something nested, you may want to recurse or similar.
To do this without modifying the script, you'll need a watcher script/program that checks for access to the script file or calls ps every so often. However, if you have that kind of access, just modifying the script is probably easier.
Edit: Apparently the commands to get the parent pid and command for it, without repeatedly calling ps, look something like:
ps -p $$ -o ppid=
cat /proc/<pid>/cmdline
(from jweyrich's answer here)
Grep for it:
grep -lr yourscript /etc /opt/anotherlikleydir
failing that, search the whole system : grep -lr yourscript /
Edit:
failing that, search in binaries too: grep -lar yourscript /
failing that, the script is either executed by a logged in user or a scripted remote login... if that's the case, try peachykeen's approach and edit the script... and why not dump a ps axf to a log too.

bash for-loop in script won't run as non-root cron script

I have a cron script that I run nightly from the system-wide /etc/crontab like this:
00 01 * * * www-data /root/scripts/image-auto-process.sh 1> /var/data/logs/cron.out 2> /var/data/logs/cron.err
It's a bash script that backs up (with rsync) some directories full of scanned jpegs, runs a php-program to batch process those jpegs (preview/thumbnails), uploads them to a server and upon success cleans out the first mentioned directories.
Everything but the last clean-out step works like a charm. However, if I run it from the commandline as the www-data user, it works. When it runs via cron as same user, it doesn't.
The last, clean-out step looks like the following:
echo "remove original scans"
for i in `find $SCAN_ORIG_DIR -mindepth 2 -type d -print | grep -v -f $EXCLUDES`; do rm -rvf $i; done
echo "job Done..."
$SCAN_ORIG_DIR is the directory to search. $EXCLUDES is a file (readable to www-data) containing lines with directories to ignore (same file is used to tell rsync what not to backup). -mindepth 2 is used in find because I only want to return subdir's of $SCAN_ORIG_DIR that also have subdirs, like $SCAN_ORIG_DIR/subdir/subsubdir.
I tried putting the above code into its own script and running it on commandline and via cron just to make sure no prior code in the script was causing the problem.
Results in commandline (not exact representation, but just to illustrate):
remove original scans
removed '$SCAN_ORIG_DIR/subdir1/subsubdir'
removed '$SCAN_ORIG_DIR/subdir2/subsubdir'
removed '$SCAN_ORIG_DIR/subdir3/subsubdir'
job Done...
Results via cron:
remove original scans
job Done...
So, I'm stumped. I sincerely hope anyone can help shine a light on what's wrong here.
Thank you very much for you time and efforts :-)
A common problem with scripts when running in cron, is that the user login scripts (.bashrc, ,bash_profile) are not executed, so some variables are missing.
BTW, it is not good practice to use the system-wide /etc/crontab. Use crontab -e to add cron jobs.

linux - process already running error

I am trying to start a process and although ps -ef|grep myprocessname does not show it running, when I invoke the script to start it it says process already running, exiting.
I have searched internet for about one hour and I can not find any answers. Can anyone help? Thank you.
#TILO: There is no file under /var/run that has a name even close to my process. Any other suggestions?
#VKRAM: This is a third party software. Any suggestions?
check under /var/run if there is a .pid file for the process you're trying to start.
e.g. /var/run/mysqld/mysqld.pid would be such a file.
That file contains the PID of the process...
run a
ps -edaf | grep PID # with the pid you find in the file
if the process is not found, you can delete the pid-file -- then try starting your process again
Try using strace on the program in question:
strace yourprogram
Shortly before it terminates, you should see the system calls it used to determine that another instance was running, and can from there reverse engineer the method it is using.
you said you can't find the PID-file...
If you can't find the PID file (maybe because some of the directories under /var/run are deeply nested),
try this to see a list of all PID-files in there:
find /var/run -type f -name '*.pid'
find /var -type f -name '*.pid'
maybe you'll see a filename that looks similar to the process name you're trying to start.
Or you can also put a grep at the end of that line and try to grep for the process name in the list.
Some programs put use also lock files -- these can be usually found under /var/lock/ or /var/lock/subsystem
If that doesn't help, try to look at the start-script that you're using , e.g. under /etc/init.d/
Look at it in detail and look for something like LOCK_FILE or PID_FILE

Can I execute nested or chained commands in UNIX shell?

Can I execute command within another command in UNIX shells?
If impossible, can I use the output of the previous command as the input of next command, as in:
command x then command y,
where in command y I want use the output of command x?
You can use the backquotes for this.
For example this will cat the file.txt
cat &grave;echo file.txt&grave;
And this will print the date
echo the date is &grave;date&grave;
The code between back-quotes will be executed and be replaced by its result.
You can do something like;
x=$(grep $(dirname "$path") file)
here dirname "$path" will run first and its result will be substituted and then grep will run, searching for the result of dirname in the file
What exactly are you trying to do? It's not clear from the commands you are executing. Perhaps if you describe what you're looking for we can point you in the right direction. If you want to execute a command over a range of file (or directory) names returned by the "find" command, Colin is correct, you need to look at the "-exec" option of "find". If you're looking to execute a command over a bunch of arguments listed in a file or coming from stdin, you need to check out the "xargs" commands. If you want to put the output of a single command on to the command line of another command, then using "$(command)" (or 'command' [replace the ' with a backquote]) will do the job. There's a lot of ways to do this, but without knowing what it is you're trying it's hard to be more helpful.
Here is an example where I have used nested system commands.
I had run "ls -ltr" on top of find command. And it executes
it serially on the find output.
ls -ltr $(find . -name "srvm.jar")

Resources