Unix process name from pid - unix

I believe what I am going to asked, will not be possible. Still trying to find if there is a way or approach that I wont be aware of.
I got a broken pipe error where I am having pid of destination process but not the name. Is there any way, I can find out the process name (which possibly already terminated) using pid.

As Barmar said in his comment, this isn't possible normally. The system forgets all information about processes as soon as they terminate.
But of course your processes might be able to comply in order to help you find out more. In case you can modify the processes in question you can let them log their PID into a special place where you can look up later which PID belonged once to which process.
This won't work for programs you cannot modify, though. In these cases it still might be possible to put a wrapper around them which first logs the PID and then execs to the wanted program.
#!/bin/bash
echo "$$: $*" >> /home/alfe/var/pid.log
exec "$#"
In case you are neither starting the program in question nor can you modify it, you are out of options I fear.

Related

Prevent automatic terminal closure/idle process in ZSH

Is there any way to make sure zsh doesn't exit when cluster administrators auto-kill all idle processes after some fairly short amount of time?
I have already figured out how to do it with tmux, but my zsh sessions keep dying and the admins won't budge on the policy. I can always leave a dumb while loop going, but that is really tedious to do at the start of every single zsh session, but it is very frustrating to come back and find that my process has exited, but I have no idea why because the shell that hosted it was killed and the output history is gone.
I use oh-my-zsh, so if there is a module in there that can do this, that would be great too.
I just added a simple script to to my .zshrc. It is an inelegant solution but it does work.
if [[ "$HOSTNAME" =~ "^myhost*" ]]; then
while true; do echo 'hi' > /dev/null; sleep 120; done &
I am sure there is a better way because this makes shell startup slower than I would like, but that is what I came up with for now.

UNIX - Stopping a custom service

I created a client-server application and now I would like to deploy it.
While development process I started the server on a terminal and when I wanted to stop it I just had to type "Ctrl-C".
Now want to be able to start it in background and stop it when I want by just typing:
/etc/init.d/my_service {stop|stop}
I know how to do an initscript, but the problem is how to actually stop the process ?
I first thought to retrieve the PID with something like:
ps aux | grep "my_service"
Then I found a better idea, still with the PID: Storing it on a file in order to retrieve it when trying to stop the service.
Definitely too dirty and unsafe, I eventually thought about using sockets to enable the "stop" process to tell the actual process to shut down.
I would like to know how this is usually done ? Or rather what is the best way to do it ?
I checked some of the files in the init.d and some of them use PID files but with a particular command "start-stop-daemon". I am a bit suspicious about this method which seems unsafe to me.
If you have a utility like start-stop-daemon available, use it.
start-stop-daemon is flexible and can use 4 different methods to find the process ID of the running service. It uses this information (1) to avoid starting a second copy of the same service when starting, and (2) to determine which process ID to kill when stopping the service.
--pidfile: Check whether a process has created the file pid-file.
--exec: Check for processes that are instances of this executable
--name: Check for processes with the name process-name
--user: Check for processes owned by the user specified by username or uid.
The best one to use in general is probably --pidfile. The others are mainly intended to be used in case the service does not create a PID file. --exec has the disadvantage that you cannot distinguish between two different services implemented by the same program (i.e. two copies of the same service). This disadvantage would typically apply to --name also, and, additionally, --name has a chance of matching an unrelated process that happens to share the same name. --user might be useful if your service runs under a dedicated user ID which is used by nothing else. So use --pidfile if you can.
For extra safety, the options can be combined. For example, you can use --pidfile and --exec together. This way, you can identify the process using the PID file, but don't trust it if the PID found in the PID file belongs to a process that is using the wrong executable (it's a stale/invalid PID file).
I have used the option names provided by start-stop-daemon to discuss the different possibilities, but you need not use start-stop-daemon: the discussion applies just as well if you use another utility or do the matching manually.

How can I pass command line input to external process in Unix

My program runs(exec..) an external program.
While running, the external program asks user [Yes/No] to proceed next step.
Instead of typing [yes] in command line, how can I pass [Yes] to the external program from my program.
Unless the external program supports a respective flag (see #Jonathan Leffler's answer), your you have control over that program's source and can add it, you have to simulate the "yes" input.
Options:
Try launching the external program by piping the output of the yes helper application to it's stdin: yes | external_program. yes is a simple tool, should you not have it, that just writes "y" to it's stdout continually.
Manually write "yes" to to stdin of the external program.
Both options require your to use pipes in one way or the other. See this for more information on how to do that.
The classic way to provide a 'yes' response on the command line is a -y option (usually with a parallel -n option to indicate a 'no' — see fsck(1)).
There's also room to argue that running the program should be a 'yes, I mean to do it' operation. However, there are times when it makes sense to specify 'yes, I really mean to do it' (such as one-time initialization of an instance of a DBMS).

have R halt the EC2 machine it's running on

I have a few work flows where I would like R to halt the Linux machine it's running on after completion of a script. I can think of two similar ways to do this:
run R as root and then call system("halt")
run R from a root shell script (could run the R script as any user) then have the shell script run halt after the R bit completes.
Are there other easy ways of doing this?
The use case here is for scripts running on AWS where I would like the instance to stop after script completion so that I don't get charged for machine time post job run. My instance I use for data analysis is an EBS backed instance so I don't want to terminate it, simply suspend. Issuing a halt command from inside the instance is the same effect as a stop/suspend from AWS console.
I'm impressed that works. (For anyone else surprised that an instance can stop itself, see notes 1 & 2.)
You can also try "sudo halt", as you wouldn't need to run as a root user, as long as the user account running R is capable of running sudo. This is pretty common on a lot of AMIs on EC2.
Be careful about what constitutes an assumption of R quitting - believe it or not, one can crash R. It may be better to have a separate script that watches the R pid and, once that PID is no longer active, terminates the instance. Doing this command inside of R means that if R crashes, it never reaches the call to halt. If you call it from within another script, that can be dangerous, too. If you know Linux well, what you're looking for is the PID from starting R, which you can pass to another script that checks ps, say every 1 second, and then terminates the instance once the PID is no longer running.
I think a better solution is to use the EC2 API tools (see: http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ for documentation) to terminate OR stop instances. There's a difference between the two of these, and it matters if your instance is EBS backed or S3 backed. You needn't run as root in order to terminate the instance - the fact that you have the private key and certificate shows Amazon that you're the BOSS, way above the hoi polloi who merely have root access on your instance.
Because these credentials can be used for mischief, be careful about running API tools from a given server, you'll need your certificate and private key on the server. That's a bad idea in the event that you have a security problem. It would be better to message to a master server and have it shut down the instance. If you have messaging set up in any way between instances, this can do all the work for you.
Note 1: Eric Hammond reports that the halt will only suspend an EBS instance, so you still have storage fees. If you happen to start a lot of such instances, this can clutter things up. Your original question seems unclear about whether you mean to terminate or stop an instance. He has other good advice on this page
Note 2: A short thread on the EC2 developers forum gives advice for Linux & Windows users.
Note 3: EBS instances are billed for partial hours, even when restarted. (See this thread from the developer forum.) Having an auto-suspend close to the hour mark can be useful, assuming the R process isn't working, in case one might re-task that instance (i.e. to save on not restarting). Other useful tools to consider: setTimeLimit and setSessionTimeLimit, and various checkpointing tools (I have a Q that mentions a couple). Using an auto-kill is useful if one has potentially badly behaved code.
Note 4: I recently learned of the shutdown command in package fun. This is multi-platform. See this blog post for commentary, and code is here. Dangerous stuff, but it could be useful if you want to adapt to Windows. I haven't tried it, though.
Update 1. Three more ideas:
You could use .Last() and runLast = TRUE for q() and quit(), which could shut down the instance.
If using littler or a script that invokes the script via Rscript, the same command line functions could be used.
My favorite package of today, tcltk2 has a neat timer mechanism, called tclTaskSchedule() that can be used to schedule the execution of an expression. You could then go crazy with the execution of stuff just before a hourly interval has elapsed.
system("echo 'rootpassword' | sudo halt")
However, the downside is having your root password in plain text in the script.
AFAIK those ways you mentioned are the only ones. In any case the script will have to run as root to be able to shut down the machine (if you find a way to do it without root that's possibly an exploit). You ask for an easier way but system("halt") is just an additional line at the end of your script.
sudo is an option -- it allows you to run certain commands without prompting for any password. Just put something like this in /etc/sudoers
<username> ALL=(ALL) PASSWD: ALL, NOPASSWD: /sbin/halt
(of course replacing with the name of user running R) and system('sudo halt') should just work.

UNIX equivalent of CreateProcessWithLogonW

What I have: the login/password for a UNIX user (alice).
Who I am: some other UNIX user (bob).
What I need to do: start a process programmatically (foo) as the other user (alice).
What the end result should be: the process is running and displays alice as the owner if a "ps" is done. For purposes of privileges, acts as if alice started it.
Basically I need to write some code that does the equivalent of "su -c 'foo' - alice"
Ideally I don't want to have to set any special bits or permissions on the executable in question (foo).
I see only two possibilites to start a process as alice on UNIX/Linux from a process owned by bob that cannot setuid itself.
call a setuid program
communicate with an already running process that can start processes as alice
Never say never, but I think this is probably impossible in any unix-portable way. The setuid(2) call (and friends) succeeds only if the current uid is either the same as the target one (modulo some subtleties about effective and real uids) or if the current uid is 0 (ie, root). That is, you can't change from one non-root uid to another.
Having the password doesn't help. The password is used for the initial authentication to the system, whether it be via login, ssh, or some GUI login dialogue, but the password is the concern of those programs alone, and not of the system as such. Put another way, the kernel doesn't care about your password, and it's the kernel that you have to talk to if you want to change your uid.
That is, you're probably therefore obliged to consider indirect routes, such as the ones Peter G mentioned.
(Yes, some unixes may have a way of doing this, but that's platform-specific).
I know I'm not adding any positive advice here, only the possibly time-saving negative advice of 'nothing to see here; move right along...'

Resources