Eigenen Prozessnamen vergeben bei Shell-Script

FatManStanding

Lt. Junior Grade
Registriert
Aug. 2021
Beiträge
386
tach,

mit

Code:
bash -c "exec -a MyProcessName sleep 99"

kann ich einen eigenen namen vergeben unter dem de prozess dann per "ps" gefunden werden kann, in dem fall wird

Code:
MyProcessName 99

gefunden. das geht aber nicht wenn ich statt dem "eingebauten" sleep ein eigenes shell-script starte. geht das irgendwie? das script liegt im ordner ~/bin und wird im terminal auch ohne eingabe des pfades gefunden.
 
nicht mega straight forward, aber kannst du im zweifelsfall so loesen:
https://stackoverflow.com/questions/3075682/how-to-set-the-process-name-of-a-shell-script
been there.

FatManStanding schrieb:
das script liegt im ordner ~/bin und wird im terminal auch ohne eingabe des pfades gefunden.
nicht unbedingt best practice. Leg das lieber in einen oder bin in deinem home ordner ind pack den in den Pfad. oder unter /opt. Meintwegen /usr/local/bin
aber liebe rkein ordner in den dein paketmanager schreibt
 
echo "foo" > /proc/$$/comm

/proc/[pid]/comm (since Linux 2.6.33)
This file exposes the process's comm value—that is, the command name associated with the process. Different threads in the same process may have different comm values, accessible via /proc/[pid]/task/[tid]/comm. A thread may modify
its comm value, or that of any of other thread in the same thread group (see the discussion of CLONE_THREAD in clone(2)), by writing to the file /proc/self/task/[tid]/comm. Strings longer than TASK_COMM_LEN (16) characters (including
the terminating null byte) are silently truncated.

This file provides a superset of the prctl(2) PR_SET_NAME and PR_GET_NAME operations, and is employed by pthread_setname_np(3) when used to rename threads other than the caller. The value in this file is used for the %e specifier in
/proc/sys/kernel/core_pattern; see core(5).
 
@ madmax2010

ich hab das erstmal so gemacht:
Code:
#!/bin/bash
#!/bin/bash ./$0
sleep 03

das script muss man dann mit "script <prozess-name>" starten und man erhält <prozess-name> als ebendiesen. blöd ist aber, dass ich den nicht per pkill <prozess-name> oder killall <prozess-name> wieder beenden kann. im bsp. oben müsste ich 'sleep' beenden. das wird aber zu einem problem wenn ich mehrere scripte habe die alle z. b. ein sleep gestartet haben und ich nur eines davon beenden will.

@ foofoobar

wenn ich das richtig verstehe wird in /proc/ für jeden gerade laufenden prozess unter dessen prozess-id eine unterordner angelegt.

so richtig hilfreich ist das aber nicht, wenn ich nicht nach dem prozessnamen (oder den von mir selbst gewählten scriptnamen) suchen kann.
 
Zuletzt bearbeitet:
FatManStanding schrieb:
wenn ich das richtig verstehe wird in /proc/ für jeden gerade laufenden prozess unter dessen prozess-id eine unterordner angelegt.

So ähnlich, schau dir mal die man-page zu proc an: "man 5 proc"

$$ ist die pid vom laufenden Prozess.
 
Man sollte wissen das der Kernel den "Prozessnamen" an zwei verschiedenen stellen speichert.
Zum einen ARG0 und zudem wird der Datei-Name auf 16 Bytes gekürzt gespeichert.

Prozess Tools wie ps, pkill etc. können je nach Argument den Prozess entweder über "/proc/pid/cmdline" oder über "/proc/pid/comm" finden, daher sollte es eigentlich reichen einen der beiden zu ändern.
pkill MyProctitle vs pkill -f ARG0

Über den bereits verlinkten symlink trick kann man beide gleichzeitig ändern. Nachteil ist das man zumindest kurz temporäre den symlink auf den Dateisystem anlegen muss.

Eine etwas ausführlichere Erklärung:

bash -c "exec -a ARG0 /tmp/tmp.wSjQKZDkHy 1 2 3"

Funktioniert nicht da der Kernel sobald er einen "shebang" findet das ursprünglich übergeben ARG0 einfach löscht und an dessen stelle den interpreter einsetzt. [1]
Also darf man sich bei der Ausführung nicht auf den "shebang" verlassen, daher stattdessen die Shell direkt aufrufen:

bash -c "exec -a ARG0 bash /tmp/tmp.wSjQKZDkHy 1 2 3"

Jetzt würde der gekürzt Datei-Name aber nicht mehr gleich Script-Name seine sondern gleich "bash". Diesen kann man über "/proc/pid/comm" ändern.

Das Ganze wird jedoch noch verwirrender in dem $0 in einer shell aus Systemsicht nicht ARG0 entspricht sondern ARG1. Diesen kann man bei Bash über BASH_ARGV0 überschreiben.


Code:
cat /tmp/tmp.wSjQKZDkHy
#!/bin/bash

echo \$0: $0
echo PID: $$
ps $$
ps -p $$
ps -fp $$

echo ---
cat /proc/$$/comm
echo ---
grep Name: /proc/$$/status
echo ---
hexdump /proc/$$/cmdline -C
sleep 100000s

Code:
# Bsp. 1
echo "BASH_ARGV0=MyBashArg0; printf 'MyProctitle' > /proc/self/comm" |  cat - /tmp/tmp.wSjQKZDkHy | bash -c "exec -a ARG0 bash /dev/stdin 1 2 3"
# $0: MyBashArg0
# PID: 38706
#     PID TTY      STAT   TIME COMMAND
#   38706 pts/4    S+     0:00 ARG0 /dev/stdin 1 2 3
#     PID TTY          TIME CMD
#   38706 pts/4    00:00:00 MyProctitle
# UID          PID    PPID  C STIME TTY          TIME CMD
# lukas      38706   25632  0 18:30 pts/4    00:00:00 ARG0 /dev/stdin 1 2 3
# ---
# MyProctitle
# ---
# Name:   MyProctitle
# ---
# 00000000  41 52 47 30 00 2f 64 65  76 2f 73 74 64 69 6e 00  |ARG0./dev/stdin.|
# 00000010  31 00 32 00 33 00                                 |1.2.3.|
# 00000016

# Suche über /proc/pid/stat (selbe info wie in /proc/pid/comm)
pkill MyProctitle

# Suche über /proc/pid/cmdline
pkill -f ARG0

# Bsp. 2
# Suche über /proc/pid/cmdline
bash -c "exec -a ARG0 bash /tmp/tmp.wSjQKZDkHy 1 2 3"
pkill -f ARG0


Prozess Umbenennung hat aus meiner Sicht nur ein paar wenig legitime Gründe wenn es geht sollte man stattdessen pidfiles verwenden und diese in $XDG_RUNTIME_DIR anlegen.
 
lukas12342 schrieb:
Prozess Umbenennung hat aus meiner Sicht nur ein paar wenig legitime Gründe wenn es geht sollte man stattdessen pidfiles verwenden und diese in $XDG_RUNTIME_DIR anlegen.
Java sollte das machen um in diesen endlosen Cmdlines den Namen des eigentlichen Programms besser finden zu können.
 
Zurück
Oben