trap signal (nicht ctrl c) fangen, um prozess zu killen

Post Reply
Message
Author
User avatar
killerhippy
Posts: 529
Joined: 19. May 2000 19:36
Contact:

trap signal (nicht ctrl c) fangen, um prozess zu killen

#1 Post by killerhippy »

Hi,

bash interna sind ja nicht sooo einfach.

Ich habe mir ein script gebastelt, das einfach alle mp3 files der eingelegten cd spielt:
<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
#!/bin/sh

DEVICE=/dev/cdrom
MOUNTPOINT=/mnt/cdrom
MOUNTOPTIONS="-tiso9660"

mount $DEVICE $MOUNTPOINT $MOUNTOPTIONS

trap 'umount $MOUNTPOINT ; exit 32' 0
FILES=`find $MOUNTPOINT -name "*.mp3" -exec echo -n {}"#" \<!--no-->;`
IFS="#"
for i in $FILES; do
echo $i
`mpg123 -y $i`
done
umount $MOUNTPOINT
</font><hr></pre></blockquote>

das spielt einfach die cd durch und damit kann ich schon zufrieden sein :)

zwei Wünsche:

- bei commando Übergabe ein random der liste
- bsp. ctrl+n mpg123 killen, nicht aber das script, damit der gegenwärtige song sofort aufhört und das nexte in der Liste gespielt wird. ctrl+c killt ja gleich alles.

kann man das so einfach mit bash hinkriegen?
Last edited by killerhippy on 14. Dec 2002 16:00, edited 2 times in total.
Es gibt keine dumme Fragen!

Killerhippy

Jochen

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#2 Post by Jochen »

Die Sache mit dem Ctrl-C ist einfach. Mein Skript dazu sieht so aus:<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">#!/bin/sh

DEVICE=/dev/cdrom
MOUNTPOINT=/mnt/cdrom
MOUNTOPTIONS="-tiso9660"

mount $DEVICE $MOUNTPOINT $MOUNTOPTIONS

trap 'umount $MOUNTPOINT ; exit 32' 0

find $MOUNTPOINT -name "*.mp3" -print | while read FILE ; do
echo $FILE
mpg123 -y $FILE
done

exit 0
</font><hr></pre></blockquote>
<li>Da das umount-Kommando immer beim Verlassen der Shell aufgerufen wird, brauchst Du es am Ende nicht noch mal angeben.
<li>Weshalb hattest Du das mpg123-Kommando in Backquotes `` eingeschlossen? Einfach nur Aufrufen tut's auch...
<li>... und dann hast Du auch direkt das gewünschte Verhalten, dass Ctrl-C nur den mpg123 abbricht, nicht die Shell. Das wird daran liegen, dass mpg123 SIGINT selbst abfängt, um ggf. ein Stück in der Liste der übergebenen Lieder weiter zu springen.

Nur die Shuffle-Sache tu ich mir jetzt nicht an. Halt, warte - es gibt wirklich nichts, was es nicht gibt! Schau mal hier: <a href="http://tiefighter.et.tudelft.nl/~arthur/rl/" target="_blank"><!--auto-->http://tiefighter.et.tudelft.nl/~arthur ... <!--auto-->

Das sollte die Sache einfach machen...

Jochen

Jochen

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#3 Post by Jochen »

... und zwar so:<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
#!/bin/sh

# Benötigt rl!

DEVICE=/dev/cdrom
MOUNTPOINT=/mnt/cdrom
MOUNTOPTIONS="-tiso9660"

if [ "$1" == "shuffle" ] ; then
SHUFFLE_CMD=rl
else
SHUFFLE_CMD=cat
fi

mount $DEVICE $MOUNTPOINT $MOUNTOPTIONS

trap 'umount $MOUNTPOINT ; exit 32' 0

find $MOUNTPOINT -name "*.mp3" -print | $SHUFFLE_CMD | while read FILE ; do
echo $FILE
mpg123 -y $FILE
done

exit 0</font><hr></pre></blockquote>

Wenn das erste Argument des Skripts "shuffle" lautet, dann ein rl zwischen find und while-Schleife flanschen, ansonsten ein schnödes cat als NOP, sozusagen.

Jochen

User avatar
killerhippy
Posts: 529
Joined: 19. May 2000 19:36
Contact:

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#4 Post by killerhippy »

@jochen:

danke für die zwei Tips.

letztes script funktioniert nur mäßig, denn (leider) habe ich cds mit leerzeichen im namen der directories und files.

aber ich werde mal rumbasteln.

thanx again.
Es gibt keine dumme Fragen!

Killerhippy

Jochen

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#5 Post by Jochen »

OK, Bugfix:<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">#!/bin/sh

# Benötigt rl!

DEVICE=/dev/cdrom
MOUNTPOINT=/mnt/cdrom
MOUNTOPTIONS="-tiso9660"

if [ "$1" == "shuffle" ] ; then
SHUFFLE_CMD=rl
else
SHUFFLE_CMD=cat
fi

mount $DEVICE $MOUNTPOINT $MOUNTOPTIONS

trap 'umount $MOUNTPOINT ; exit 32' 0

<b>IFS=""</b>

find $MOUNTPOINT -name "*.mp3" -print | $SHUFFLE_CMD | while read FILE ; do
echo "$FILE"
mpg123 -y "$FILE"
done

exit 0
</font><hr></pre></blockquote>Wenn read die Variable FILE füllen will, zerlegt die Shell vorher die Zeile anhand der Trennzeichen in IFS. Ist IFS leer, wird die Zeile der Variablen unverändert zugewiesen. Da dann aber Leerzeichen in FILE vorkommen können, muss jedes weitere Auftreten von $FILE in Anführungszeichen gesetzt werden, damit die Shell dort nicht wieder den Inhalt zerlegt.

Jochen

User avatar
killerhippy
Posts: 529
Joined: 19. May 2000 19:36
Contact:

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#6 Post by killerhippy »

toll, dann erschlägt sich ja die frage, was ich aus `man rl` inzwischen gebastelt hatte:

<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
#!/bin/sh

DEVICE=/dev/cdrom
MOUNTPOINT=/mnt/cdrom
MOUNTOPTIONS="-tiso9660"

mount $DEVICE $MOUNTPOINT $MOUNTOPTIONS

trap 'umount $MOUNTPOINT ; exit 32' 0

if [ "$1" == "shuffle" ] ; then
find $MOUNTPOINT -name '*.mp3' -print0 \
| rl -0 | xargs -n 1 -0 mpg123 -y
else
find $MOUNTPOINT -name '*.mp3' -print0 \
| xargs -n 1 -0 mpg123 -y
fi

exit 0
</font><hr></pre></blockquote>

wobei das shuffle schön funktioniert, ctrl+c aber auch wieder nicht nur mpg123 abschiesst, sondern auch das script.
Es gibt keine dumme Fragen!

Killerhippy

Jochen

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#7 Post by Jochen »

Oh je... Gerade habe ich festgestellt, dass bei meinem RH7.3, auf der ich die ganze Zeit teste, "/usr/bin/mpg123" nur ein Link auf "mpg321" ist. Damit rede ich die ganze Zeit von einem anderen Programm, ohne es zu merken... <img src="http://www.pl-forum.de/UltraBoard/Images/Sad.gif" border="0" align="middle">

Sorry. Mein letzter Tip wäre also, mpg321 statt mpg123 zu benutzen. Denn bei mir haut es genau so hin, wie Du es gerne hättest!

Jochen

User avatar
killerhippy
Posts: 529
Joined: 19. May 2000 19:36
Contact:

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#8 Post by killerhippy »

wieso meinst du das denn? das letzte script, was du gepostet hast, funktioniert super und ich freu' mir 'n ast ab dabei :)

handelt mpg321 die signals anders als mpg123???

also ich bin's zufrieden, wie man so schön sagt...
Es gibt keine dumme Fragen!

Killerhippy

Jochen

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#9 Post by Jochen »

Sagtest Du nicht, ctrl-c würde wieder das ganze Skript abbrechen statt nur den gerade laufenden mpg123?

Jochen

User avatar
killerhippy
Posts: 529
Joined: 19. May 2000 19:36
Contact:

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#10 Post by killerhippy »

das bezog sich auf meinen eigenen murks, nicht auf deine scripte.

das "Ok, Bugfix" script, ist das, was gut läuft und die cd in ordered oder shuffle mode abspielen kann.

trap will bloss nicht mehr so richtig. von 'ner anderen konsole geKILLed werden trap kommandos ausgeführt.
von der gleichen konsole funktioniert das nicht mehr. lass mal beschreiben:
1x ctrl-c -> killt diesen song, weiter mit nexter song
2x ctrl-c -> ""
ctrl-c gedrueckt halten -> killt diesen und nexten song, killt das script, trap aber auch. keine konsolenangabe diesbezüglich.

man bash sagt dazu:
The ERR trap is not executed if the failed command
is part of an until or while loop,

ok, dann frage ich mich bloss, warum ein entferntes kill funktioniert
Es gibt keine dumme Fragen!

Killerhippy

User avatar
killerhippy
Posts: 529
Joined: 19. May 2000 19:36
Contact:

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#11 Post by killerhippy »

Inzwischen habe ich herausgefunden, worin meine trap-Schwierigkeit liegt.

wenn ich solange CTRL-C drücke, daß mpg123 beendet wird, und keinen neuen Song anfängt und wieder loslasse, kommt trap zum Zuge.

wenn ich zulange CTRL-C drücke, wird wohl auch trap vom CTRL-C erledigt. Kann man das Verhalten beeinflussen? Ich konnte da in manpages nichts drüber finden.

Andere Frage: Ich freu' mich so über dieses miniscript, bist du Jochen damit einverstanden, wenn ich's als Kurztipp bei Prolinux einsende?
Schreib' mir ne email, wenn du mit vollem Namen unter den Autoren mit aufgenommen werden willst.
Es gibt keine dumme Fragen!

Killerhippy

Jochen

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#12 Post by Jochen »

Von mir aus gerne. Verweise einfach auch auf den Thread hier im Forum, dann jat sich das mit der Namensnennung auch schon erledigt. <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle">

Jochen

rattengift

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#13 Post by rattengift »

wär doch nett, wenn man jetzt noch das shuffle selber programmieren würde und so nicht mehr auf das "rl" angewiesen wäre. eigentlich gar nicht so schwierig. die datei-liste wird in ein tmp-file geschrieben (löschen in der trapfunction nicht vergessen), mit $RANDOM % $(wc -l tmpfile) würfelt man eine zeilennummer und spielt das file ab. dann muss nur noch die gewählte zeile aus dem tmp-file gelöscht werden, aber dafür gibts sicher auch ne einfache lösung.

rattengift

Re: trap signal (nicht ctrl c) fangen, um prozess zu killen

#14 Post by rattengift »

@rattengift

> wär doch nett, wenn man jetzt noch das shuffle selber programmieren würde und so nicht mehr auf das "rl" angewiesen wäre.
> eigentlich gar nicht so schwierig.

hm, schwierig ist es tatsächlich nicht, nur leider erheblich langsamer als das "original-rl" (wenn man mit bash gegen C antritt hat man eben schon verloren <img src="http://www.pl-forum.de/UltraBoard/Images/Sad.gif" border="0" align="middle"> ).
ich habs interessehalber mal zusammengebastelt. hier der code:<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">#!/bin/bash

function rl () # randomize lines
{ # input: file aus $1 (oder stdin falls kein $1 angegeben). ausgabe auf stdout

local FILE=$1 # input
local FILEIN=/tmp/tmp.shuffle$$ # datei mit den noch verbliebenen zeilen

# kopiere input in tmp-datei und zähle zugleich die zeilen:
local LOC=$(cat $FILE | tee $FILEIN | wc -l)

while [ $LOC -gt 0 ]; do
# würfle eine zeile. (mit rnd aus 0..32767 liefert "rnd % loc" eine zahl aus 0..loc-1)
local LINEPICK=$[ 1 + $RANDOM % $LOC ]

# gib gewählte zeile aus:
sed ${LINEPICK}!d $FILEIN

# entferne gewählte zeile aus liste
#("ed" ist etwas schneller als "cat $FILEIN | sed ${LINEPICK}d > $FILEIN")
ed -s $FILEIN << HERE
${LINEPICK}d
wq
HERE

LOC=$[ $LOC - 1 ]
done

rm -f $FILEIN
}

rl $1
exit 0</font><hr></pre></blockquote>der ansatz ist wohl einigermassen brute force (sed/ed werden $LOC mal aufgerufen), aber spezielle optimierungen sind mir jetzt nicht eingefallen.
für eine datei von 300 zeilen brauchts auf meinem (recht schnellen) rechner gähnend lange 2 sekunden. wenn man das playerskript etwas umbauen würde (so dass nicht das ganze shuffle gleich am anfang erledigt wird, sondern jeder song erst bei bedarf ausgelost wird) würde man die performance-einbusse allerdings nicht mehr spüren (bei mir wärens <0.01sec pro song).

Post Reply