[Ubuntu] /bin/sh en /bin/bash functioneren niet?

Pagina: 1
Acties:

Onderwerpen


Verwijderd

Topicstarter
Ik was bezig met het installeren van PMS (PlayStation3 Media Server) op mijn linux servertje, en dat ging al vrij snel heel goed, tot het moment dat ik de software als service wilde gaan draaien. Daarvoor heb ik een initscriptje van het internet geplukt, maar dat werkt niet geheel zoals gewenst. Ik heb sterk het gevoel dat dat komt doordat de shell commando's die aangeroepen worden in dat script (bijvoorbeeld een 'cd') niet werken. Doortesten leverde dit soort dingen op:

code:
1
2
3
4
5
6
7
kryz@orcrist:~$ touch bla1
kryz@orcrist:~$ ls
bla1
kryz@orcrist:~$ /bin/sh touch bla2
/bin/sh: Can't open touch
kryz@orcrist:~$ /bin/bash touch bla3
/bin/touch: /bin/touch: cannot execute binary file

Nou ben ik geen linux goeroe, maar dit hoort toch gewoon te werken? Wat heb ik in hemelsnaam vernaggeld op mijn machine dat dit niet werkt? :)

Even wat systeeminfo: Ubuntu Jaunty, 2.6.28-11-server kernel, geen monitor / X, PATH lijkt niets te missen (/home/kryz/bin:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/games:/usr/X11R6/bin/:/usr/lib/xcdroast-0.98/bin/).

Het zal vast wel weer een ontzettend domme fout van me zijn, maar ik probeer nu al anderhalve avond dit script werkend te krijgen, en dit is toch wel heel vervelend. Als iemand een hint heeft dan ben ik zeer benieuwd, want google leverde me tot nu toe ook weinig op (en zoeken op /bin/sh en /bin/bash leveren nogal veel resultaten op).

  • -ko-
  • Registratie: Oktober 2006
  • Laatst online: 09-09 16:32

-ko-

Leidend Voorwerp

Je voert het script uit door naar de dir te CD'en en dan ./<SCRIPTNAME> uit te voeren. Jij rijgt het shell commando en het touch commando aan elkaar, om het vervolgens een file uit te willen voeren.

Wa Doede Nou


Verwijderd

Topicstarter
-ko- schreef op woensdag 23 september 2009 @ 20:23:
Je voert het script uit door naar de dir te CD'en en dan ./<SCRIPTNAME> uit te voeren. Jij rijgt het shell commando en het touch commando aan elkaar, om het vervolgens een file uit te willen voeren.
Hmm, juischt, mijn testmethode is dus gewoon dom, en toont helemaal niets aan. ;) Helaas ben ik nog niet van mijn probleem af, maar goed dat je me op mijn onzin gewezen hebt.

  • d1ng
  • Registratie: Augustus 2009
  • Laatst online: 06-05-2024
Kun je iets specifieker zijn ?
Want enige wat ik hieruit kan halen = Ik heb een script die niet werkt.

  • zomertje
  • Registratie: Januari 2000
  • Laatst online: 11-09 12:39

zomertje

Barisax knorretje

Meestal geef je in een script de hele paden aan naar commando's zodat je zeker weet dat ie het juiste commando kan vinden. Als je een script dan runt als een andere user bijvoorbeeld. Niet iedere user heeft dezelfde $PATH setting waarschijnlijk :)

het ultieme jaargetijde.... | #!/usr/bin/girl | Art prints and fun


  • sam.vimes
  • Registratie: Januari 2007
  • Laatst online: 08-06 08:44
code:
1
bash -c 'touch bla2'

man bash zegt:
If arguments remain after option processing, and neither the -c nor the -s option has been supplied, the first argument is assumed to be the name of a file containing shell commands.
touch is geen shellscript maar een binaire executable.

Verwijderd

Topicstarter
d1ng schreef op woensdag 23 september 2009 @ 20:43:
Kun je iets specifieker zijn ?
Want enige wat ik hieruit kan halen = Ik heb een script die niet werkt.
Wat er eigenlijk staat is: ik heb een script dat niet werkt, en ik denk dat dat komt vanwege een probleem met /bin/sh / /bin/bash, maar -ko- heeft mij op mijn fout gewezen. Nu heb ik nog steeds een script dat niet werkt, maar dat is een dusdanig specifiek script dat ik me afvraag of dat probleem hier wel thuishoort. Dus eigenlijk zou je kunnen zeggen dat na -ko-'s antwoord het topic al klaar was.
zomertje schreef op woensdag 23 september 2009 @ 21:06:
Meestal geef je in een script de hele paden aan naar commando's zodat je zeker weet dat ie het juiste commando kan vinden. Als je een script dan runt als een andere user bijvoorbeeld. Niet iedere user heeft dezelfde $PATH setting waarschijnlijk :)
Dat is bij een customised script dat je als service wil draaien natuurlijk niet echt een probleem, omdat op de machine waarop je het script hebt aangepast altijd dezelfde user het script zal draaien.

Ik kan op zich wel even het eigenlijke probleem schetsen. De software is dus PMS, met de volgende eigenschappen:

- Het is java software
- De software zelf wordt gestart middels een shell script, PMS.sh, die netjes een x-bit heeft staan
- In dezelfde directory (bij mij op dit moment nog even /usr/src/pms-linux-1.10.5) staat PMS.conf, de configuratie voor de software
- De software start een UPnP media server, die verschillende mediatypen kan aanbieden aan een UPnP media client, zoals de PS3
- Er wordt gebruikgemaakt van allerlei codecs om die media te tonen

Dan het probleem:

- Ik draai deze software op mijn headless linux server, die altijd aan staat, en waar ook al mijn media op is opgeslagen
- Als ik die machine een keer reboot om wat voor reden dan ook, dan wil ik natuurlijk dat die media server vanzelf weer opstart, vandaar dat ik hem als service wil gebruiken
- Het init script dat ik gebruik om de software te starten geeft problemen; ik heb het vermoeden dat er problemen zijn met het uitvoeren van shell commando's, al weet ik het niet helemaal zeker, maar 1 van de dingen die fout gaan is dat de directory waarin de software staat niet gevonden kan worden door het shell script; de software start wel, maar de PMS.conf file kan niet gevonden worden, wat betekent dat de default config gebruikt wordt (die onbruikbaar is)

Het init script ziet er als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#! /bin/sh

### BEGIN INIT INFO
# Provides:      pms
# Required-Start:   $network $local_fs $remote_fs
# Required-Stop:
# Default-Start:   2 3 4 5
# Default-Stop:      0 1 6
# Short-Description:   PS3 UPnP Media Server
### END INIT INFO

# Source init-functions:
source /lib/lsb/init-functions

# Script variables:
MONTH=`date +%Y-%m`
PMS_ROOT="/usr/src/pms-linux-1.10.5"
PMS_LOG="/var/log/pms/pms-$MONTH.log"
DESC="PS3 UPnP Media Server"
NAME="PMS.sh"

# Path to executable:
DAEMON="$PMS_ROOT/$NAME"

# Run as user/group [UPDATE THESE TO MAKE VALID]:
PMSUSER=kryz
PMSGROUP=kryz

# update PATH:
PATH="$PMS_ROOT:${PATH:+$PATH:}/usr/sbin:/sbin"

# export env-vars
export PATH PMS_ROOT PMS_LOG

# Exit if the package is not installed
if [ ! -x "$DAEMON" ]; then {
   echo "Couldn't find $DAEMON or not executable"
   exit 99
    }
fi

#
# Function that starts the daemon/service
#
do_start() {
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    cd "$PMS_ROOT"
    start-stop-daemon --start --quiet --chuid $PMSUSER:$PMSGROUP --exec $DAEMON --test > /dev/null \
   || return 1
    start-stop-daemon --start --quiet --chuid $PMSUSER:$PMSGROUP --exec $DAEMON \
   || return 2
}


#
# Function that stops the daemon/service
#
do_stop() {
    # Return
    #   0 if daemon has been stopped
    #   1 if daemon was already stopped
    #   2 if daemon could not be stopped
    #   other if a failure occurred
    start-stop-daemon --stop --signal 2 --retry 5 --quiet --name java
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    return "$RETVAL"
}

case "$1" in
    start)
   log_daemon_msg "Starting $DESC" "$NAME"
   do_start
   case "$?" in
       0|1) log_end_msg 0 ;;
       2) log_end_msg 1 ;;
   esac
   ;;
    stop)
   log_daemon_msg "Stopping $DESC" "$NAME"
   do_stop
   case "$?" in
       0|1) log_end_msg 0 ;;
       2) log_end_msg 1 ;;
   esac
   ;;
    *)
   echo "Usage: $SCRIPTNAME {start|stop}" >&2
   exit 3
   ;;
esac

exit 0

Het PMS.sh bestand:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/sh

DIRNAME=`dirname $0`


# OS specific support (must be 'true' or 'false').
cygwin=false;
case "`uname`" in
CYGWIN*)
cygwin=true
;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$PMS_HOME" ] &&
PMS_HOME=`cygpath --unix "$PMS_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

# Setup PMS_HOME
if [ "x$PMS_HOME" = "x" ]; then
        PMS_HOME=`cd $DIRNAME/; pwd`
fi
export PMS_HOME

# Setup the JVM
if [ "x$JAVA" = "x" ]; then
        if [ "x$JAVA_HOME" != "x" ]; then
                JAVA="$JAVA_HOME/bin/java"
        else
                JAVA="java"
        fi
fi

# Setup the classpath
PMS_JAR="$PMS_HOME/pms.jar"

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
        PMS_HOME=`cygpath --path --windows "$PMS_HOME"`
        JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
        PMS_CLASSPATH=`cygpath --path --windows "$PMS_CLASSPATH"`
fi

# Sanitycheck environment
[ "x$PMS_ROOT" = "x" ] && echo "[ERROR] Environment variable 'PMS_ROOT' not set properly!" && exit 1
[ "x$PMS_LOG" = "x" ] && echo "[ERROR] Environment variable 'PMS_LOG' not set properly!" && exit 1

# Execute the JVM
exec "$JAVA" $JAVA_OPTS -Xmx768M -Djava.encoding=UTF-8 -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true -jar "$PMS_JAR" "$@" 2>&1 >> "$PMS_LOG" &

Bij het uitvoeren van het init script krijg ik dit soort meldingen:
code:
1
2
3
4
kryz@orcrist:~$ /etc/init.d/PS3MediaServerd start
/etc/init.d/PS3MediaServerd: 13: source: not found
/etc/init.d/PS3MediaServerd: 94: log_daemon_msg: not found
/etc/init.d/PS3MediaServerd: 94: log_end_msg: not found

Nog wat kleine opmerkingen: bij het runnen van PMS.sh zelf, als user kryz, werkt het dus wel (als je maar in de juiste directory staat). Alleen als je het init script draait wordt de juiste directory dus niet gevonden (en misschien gaan er nog wel andere dingen mis, maar daar heb ik dan geen benul van).

Ik heb me rot gezocht, maar de oorzaak vind ik maar niet.

  • sam.vimes
  • Registratie: Januari 2007
  • Laatst online: 08-06 08:44
/etc/init.d/PS3MediaServerd: 13: source: not found
Je script wordt uitgevoerd door /bin/sh (zie de eerste regel, achter de #!). 'source' is een intern bash-commando. Op veel linux-systemen is /bin/sh een symlink naar /bin/bash. Op jouw systeem niet; bij jou is het waarschijnlijk dash of ash. dash en ash zijn veel meer compatible met de originele Bourne-shell en kennen het interne commando 'source' niet. Daar heet dat commando '.' (een punt).
Vervang
code:
1
#!/bin/sh

door
code:
1
#!/bin/bash

en je script zal waarschijnlijk werken.

Je zou ook
code:
1
source /lib/lsb/init-functions

kunnen vervangen door
code:
1
. /lib/lsb/init-functions

maar ik weet niet hoeveel meer bash-specifieke constructies er verder nog gebruikt zijn waar je dan tegenaan zult lopen.

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 10-09 19:53

odysseus

Debian GNU/Linux Sid

Wat voor commando zou 'log_daemon_msg' (en de andere vergelijkbare aanroepen) moeten zijn? En hoe moet de shell weten wat hij daar moet doen? Als je daar een executable wil aanroepen, dan zal je het volledige pad mee moeten geven (of eerst met 'cwd' naar de juiste directory gaan). Werkt het met het specificeren van het volledige pad wel?

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


Verwijderd

Topicstarter
sam.vimes schreef op woensdag 23 september 2009 @ 22:08:
Je script wordt uitgevoerd door /bin/sh (zie de eerste regel, achter de #!). 'source' is een intern bash-commando. Op veel linux-systemen is /bin/sh een symlink naar /bin/bash. Op jouw systeem niet; bij jou is het waarschijnlijk dash of ash. dash en ash zijn veel meer compatible met de originele Bourne-shell en kennen het interne commando 'source' niet. Daar heet dat commando '.' (een punt).
Interesting. Heb je voorstel voor vervanging gedaan, en inderdaad, de foutmeldingen mbt source, log_daemon_msg en log_end_msg zijn verdwenen. En ik snap ook nog waarom, da's helemaal fijn. :D Echter, de service start nog steeds niet op in de juiste configuratie, waarschijnlijk omdat er niet naar de juiste directory gegaan wordt. De regels uit de log die dat aanwijzen:

code:
1
2
[main] TRACE 22:20:03.365 Error in accessing debug.log...
[main] TRACE 22:20:03.866 Created socket: /192.168.0.2:5001

debug.log is een file in de pms root directory. Daarbij opent het programma een socket op port 5001, wat de default is, maar in de config is die gewijzigd naar 5010.
odysseus schreef op woensdag 23 september 2009 @ 22:12:
Wat voor commando zou 'log_daemon_msg' (en de andere vergelijkbare aanroepen) moeten zijn? En hoe moet de shell weten wat hij daar moet doen? Als je daar een executable wil aanroepen, dan zal je het volledige pad mee moeten geven (of eerst met 'cwd' naar de juiste directory gaan). Werkt het met het specificeren van het volledige pad wel?
Zijn log_daemon_msg en log_end_msg geen onderdeel van /lib/lsb/init-functions? Ik ken het zelf niet, en zoals gezegd heb ik het init script volledig zelf eigenhandig gestolen van het internet, maar mijn vermoeden was dat die source regel daarvoor bedoeld was (en even googlen bevestigt mijn vermoeden). En omdat het een init script betreft, begrijp ik wel dat het handig kan zijn een specifieke init-functie-library te gebruiken.

[ Voor 3% gewijzigd door Verwijderd op 23-09-2009 22:44 ]


  • sam.vimes
  • Registratie: Januari 2007
  • Laatst online: 08-06 08:44
Echter, de service start nog steeds niet op in de juiste configuratie, waarschijnlijk omdat er niet naar de juiste directory gegaan wordt.
Meten is weten.

Ik zou er mee beginnen de directory af te drukken vlak voordat je een cd uitvoert. Bijvoorbeeld door de optie set -x op te nemen in het script (echo commands) of door
code:
1
cd "$PMS_ROOT"
en dergelijke te laten voorafgaan door een regel
code:
1
echo cd "$PMS_ROOT"

En je kunt natuurlijk op verschillende plekken een 'pwd' in je scripts zetten...

Verwijderd

Topicstarter
Heel goed, en goede hints, dat helpt me een beetje. Wat er gebeurt: er wordt wel een 'cd' gedaan in het init script, maar bij het starten van het PMS.sh script ben ik gewoon weer in /. Dan is vervolgens voor mij even de vraag, wat zou het volgende stukje script moeten doen:
code:
1
2
3
if [ "x$PMS_HOME" = "x" ]; then
        PMS_HOME=`cd $DIRNAME/; pwd`
fi

Dit is de enige plek waar een 'cd' voorkomt in het PMS.sh script, dus daar zou het moeten gebeuren. Ik begrijp alleen niet precies wat men nou probeert te doen met die variabele en die commando's.

Edit: ik heb nu dus gewoon maar even een 'cd "$PMS_HOME"' na die if statement geplaatst, en dan werkt het. Vraag ik me nog steeds af waarom dat zo moet (en volgens mij doe ik iets vies wat helemaal niet nodig zou moeten zijn), maar het probleem is in principe opgelost.

Allen bedankt voor de hulp. :)

[ Voor 18% gewijzigd door Verwijderd op 24-09-2009 13:03 ]


Verwijderd

maak gebruik van het set -x comando ( op regel 2 van elk script) om te debuggen
dat zorgt er voor dat je het resultaat van elk commando en variabele in het script op executie tijd ziet

  • laurencevde
  • Registratie: November 2001
  • Laatst online: 29-09-2024
Dat stukje code kijkt of PMS_HOME leeg is, zo ja, cd't ie naar DIRNAME, wat even daarboven ingesteld is op het pad van het script wat uitgevoerd wordt, en zet-ie dat als PMS_HOME. (dus /usr/src/pms-linux-1.10.5 als het script was gestart als /usr/src/pms-linux-1.10.5/PMS.sh, of . als je al in de dir stond, en het script als gewoon PMS.sh startte.)
Komt erop neer dat-ie zorgt dat-ie in de goede folder staat, en PMS_HOME goed staat.

Maar bij jou staat PMS_HOME al ingesteld, en wordt dat dus niet gedaan.
Blijkbaar start start-stop-daemon je script vanuit /, en moet je dus idd zelf even naar PMS_HOME cd-en...

Have a taste of freedom. It is sometimes a bitter pill. To me though, this is the sweetness of the GPL


Verwijderd

Topicstarter
laurencevde schreef op donderdag 24 september 2009 @ 18:27:
Dat stukje code kijkt of PMS_HOME leeg is, zo ja, cd't ie naar DIRNAME, wat even daarboven ingesteld is op het pad van het script wat uitgevoerd wordt, en zet-ie dat als PMS_HOME. (dus /usr/src/pms-linux-1.10.5 als het script was gestart als /usr/src/pms-linux-1.10.5/PMS.sh, of . als je al in de dir stond, en het script als gewoon PMS.sh startte.)
Komt erop neer dat-ie zorgt dat-ie in de goede folder staat, en PMS_HOME goed staat.

Maar bij jou staat PMS_HOME al ingesteld, en wordt dat dus niet gedaan.
Blijkbaar start start-stop-daemon je script vanuit /, en moet je dus idd zelf even naar PMS_HOME cd-en...
Maar dat is dus het gekke: als ik voor die if-statement keek wat het resultaat was van "x$PMS_HOME", dan was dat inderdaad 'x'. Dus aan het if-statement werd voldaan... Oh well, een extra cd commando toevoegen doet geen pijn, maar ik vind het wel vervelend als ik het niet snap. ;)

  • vanaalten
  • Registratie: September 2002
  • Laatst online: 21:38
laurencevde schreef op donderdag 24 september 2009 @ 18:27:
Dat stukje code kijkt of PMS_HOME leeg is, zo ja, cd't ie naar DIRNAME, wat even daarboven ingesteld is op het pad van het script wat uitgevoerd wordt, en zet-ie dat als PMS_HOME. (dus /usr/src/pms-linux-1.10.5 als het script was gestart als /usr/src/pms-linux-1.10.5/PMS.sh, of . als je al in de dir stond, en het script als gewoon PMS.sh startte.)
Komt erop neer dat-ie zorgt dat-ie in de goede folder staat, en PMS_HOME goed staat.

Maar bij jou staat PMS_HOME al ingesteld, en wordt dat dus niet gedaan.
Blijkbaar start start-stop-daemon je script vanuit /, en moet je dus idd zelf even naar PMS_HOME cd-en...
Ik heb eens wat testjes gedaan omdat ik er een beetje m'n twijfels over had, maar bovenstaande klopt niet precies.
code:
1
2
3
if [ "x$PMS_HOME" = "x" ]; then
        PMS_HOME=`cd $DIRNAME/; pwd`
fi

De eerste regel controleert inderdaad of $PMS_HOME leeg is. Zo niet, dan voert hij volgens mij in een nieuwe, tijdelijke shell het cd $DIRNAME en pwd commando uit en maakt PMS_HOME gelijk aan het resultaat van die pwd. Als alles goed gaat is $PMS_HOME en $DIRNAME dus gelijk, maar volgens mij loopt de rest van het script niet door in die directory van PMS_HOME maar in de oorspronkelijke directory.

Als test heb ik het volgende script even geprobeerd:
code:
1
2
3
4
5
6
7
#!/bin/sh
echo -n "Huidige directory: "
pwd
a=`cd /home/vanaalten/music; pwd`;
echo "Output van het vage commando: " $a
echo -n "En de vervolg-directory:"
pwd

... geeft, wanneer uitgevoerd:
code:
1
2
3
Huidige directory: /home/vanaalten/tmp
Output van het vage commando:  /home/vanaalten/music
En de vervolg-directory:/home/vanaalten/tmp

(en indien bash i.p.v. sh gebruikt: zelfde resultaat)
Je ziet: de 'cd' is niet blijvend.

Die cd zelf toevoegen lijkt dus zinnig - al vraag ik mij wel af, bij een script wat blijkbaar door anderen zo gebruikt wordt, waarom het elders dus wel goed werkt. Ofwel, wat staat er na verder nog in dat blijkbaar echt in die directory uitgevoerd moet worden? Verder debuggen, dus. Of tevreden zijn met het resultaat en in onnozelheid verder leven... ;)

  • ajvdvegt
  • Registratie: Maart 2000
  • Laatst online: 13-08 16:01
Dat klopt precies; de 'cd' opdracht staat tussen backticks, en dan wordt een nieuwe shell gestart waarin de opdracht wordt uitgevoerd. PMS_HOME wordt dus min of meer gelijk aan $DIRNAME (maar de truc met 'cd' heeft vast nut als er symlinks in het pad zitten ofzo).

Vervolgens wordt PMS_HOME gebruikt om je jar file te vinden: PMS_JAR="$PMS_HOME/pms.jar" (regel 38). Het maakt dus dat 'cd' geen effect lijkt te hebben; het jar bestand wordt via een absoluut pad benaderd.

I don't kill flies, but I like to mess with their minds. I hold them above globes. They freak out and yell "Whooa, I'm *way* too high." -- Bruce Baum


Verwijderd

Topicstarter
vanaalten bevestigt idd wat ik al een beetje vermoedde: die actie is alleen maar gedaan om PMS_HOME gelijk aan DIRNAME te maken (en dus niet om daadwerkelijk 'cd $DIRNAME' uit te voeren), en ik denk dat ajvdvegt ook een punt heeft dat die rare truc nuttig kan zijn als er symlinks in het spel zijn. Maar dan vraag ik me toch af hoe de originele schrijver van dit verhaal het werkend kreeg... Misschien verwees zijn /bin/sh wel naar een shelltype die de current dir van het init script zou overnemen?

[ Voor 6% gewijzigd door Verwijderd op 24-09-2009 22:50 ]

Pagina: 1