Variableninhalt wird nicht gespeichert

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von Gast123, 21.09.2011.

  1. #1 Gast123, 21.09.2011
    Zuletzt von einem Moderator bearbeitet: 21.09.2011
    Gast123

    Gast123 Guest

    Hallo Leute,

    ich habe ein seltsames Problem, dass in einem Shellskript eine Funktion den Inhalt einer Variablen nicht dauerhaft speichert.
    Das Skript befindet sich mit einer Beispieldatei im Anhang.
    Ich habe im Skript bereits echos eingebaut um den Status der Variable abzufragen.
    Es geht um die Variable "BPM", die man als zweiten Parameter dem Skript übergeben kann, oder als erste Zeile in die Musikdatei schreiben kann, oder sonst den Standardwert "120" annimmt.
    Ich stehe echt auf dem Schlauch, warum das in der Funktion "play_note" funktioniert, nicht aber in "lineOK".
    Vielleicht könnt ihr mir helfen.

    Beste Grüße
    Schard

    Script:
    Code:
    #! /bin/bash
    
    export BPM=""
    
    noteOK() {
    	return 0
    }
    
    setBPM() {
    	echo "BPM=$BPM"
    	if [ -n "$1" ]; then
    		if [ -z "$BPM" ]; then
    			BPM=$1
    			echo Set BPM to "$BPM"
    		fi
    	fi
    }
    
    timeOK() {	
    	TIME=$@
    	# Note length must be between 1 and 16
    	if [ $TIME -ge 1 ]; then
    		if [ $TIME -le 16 ]; then
    			return 0
    		else
    			echo -e "ERROR:\tLength too long!" >&2
    			return 1
    		fi
    	else
    		echo -e "ERROR:\tLength too short!" >&2
    		return 2
    	fi
    }
    
    lineOK() {
    	LINE="$@"
    	if [ "$LINE" == "$(echo -e "`echo "$LINE" | cut -f 1`\t`echo "$LINE" | cut -f 2`")" ]; then
    		if (noteOK) ; then
    			if (timeOK `echo "$LINE" | cut -f 2`) ; then
    				return 0
    			fi
    		fi
    	# First line may specify fix BPM for the music
    	elif [ "$LINE" == "`echo "$LINE" | cut -f 1`" ]; then
    		if [ -z "$BPM" -a -n "$LINE" ]; then
    			setBPM `echo "$LINE" | cut -f 1`
    		fi
    		return 1
    	fi
    	return 2
    }
    
    # Decode node to its specific frequency
    tone() {
    	case "$1" in
    		"AA")	echo "220.0";;
    		"BB"|"HH")	echo "246.9";;
    		"C")	echo "261.6";;
    		"C#")	echo "277.2";;
    		"D")	echo "293.7";;
    		"D#")	echo "311.1";;
    		"E")	echo "329.6";;
    		"F")	echo "349.2";;
    		"F#")	echo "370.0";;
    		"G")	echo "392.0";;
    		"G#")	echo "415.3";;
    		"A")	echo "440.0";;
    		"A#")	echo "466.2";;
    		"B"|"H")	echo "493.9";;
    		"c")	echo "523.2";;
    		"c#")	echo "554.4";;
    		"d")	echo "587.4";;
    		"d#")	echo "622.2";;
    		"e")	echo "659.2";;
    		"f")	echo "698.4";;
    		"f#")	echo "740.0";;
    		"g")	echo "784.0";;
    		"g#")	echo "830.6";;
    		"a")	echo "880.0";;
    		"a#")	echo "932.4";;
    		"b"|"h")	echo "987.8";;
    		# Pauses are at 1 Hz (not hearable)
    		"p"|"P")	echo "1";;
    		*)	echo "$1"
    	esac
    }
    
    # Play a note for a certain time
    play_note() {
    	# Default BPM (if neither specified as argument, nor in music file)
    	setBPM 120
    	BPMS=$((60*1000/$BPM))
    	TONE=$1
    	LENGTH=$2
    	TIME=$(($BPMS*$LENGTH/16))
    
    	beep -f `tone $TONE` -l $TIME
    }
    
    play() {
    	FILE="$1"
    
    	while read LINE; do
    		if (lineOK "$LINE") ; then
    			echo "BPM=$BPM"
    			play_note $LINE
    		fi
    	done < $FILE
    }
    
    FILE="$1"
    
    if [ -f "$FILE" ]; then
    	setBPM $2
    	play "$FILE"
    else
    	echo -e "ERROR:\tMusic file not found" 1>&2
    fi
    Beispiel-Music File:
    Code:
    100
    G	8
    F	4
    E	8
    D	8
    C	8
    D	8
    E	8
    C	8
    D	4
    E	4
    F	4
    D	4
    E	12
    D	4
    C	8
    BB	8
    C	8
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 Gast123, 21.09.2011
    Gast123

    Gast123 Guest

    Hm,

    interessanter Weise geht es, wenn ich in "play()" "lineOK()" außerhalb der if-Abfrage aufrufe:
    Code:
    #! /bin/bash
    
    BPM=""
    
    FILE="$1"
    
    noteOK() {
    	return 0
    }
    
    setBPM() {
    	echo "BPM=$BPM"
    	if [ -n "$1" ]; then
    		if [ -z "$BPM" ]; then
    			BPM=$1
    			echo -e "Set BPM to \"$BPM\""
    		fi
    	fi
    }
    
    timeOK() {	
    	TIME=$@
    	# Note length must be between 1 and 16
    	if [ $TIME -ge 1 ]; then
    		if [ $TIME -le 16 ]; then
    			return 0
    		else
    			echo -e "ERROR:\tLength too long!" >&2
    			return 1
    		fi
    	else
    		echo -e "ERROR:\tLength too short!" >&2
    		return 2
    	fi
    }
    
    lineOK() {
    	LINE="$@"
    	if [ "$LINE" == "$(echo -e "`echo "$LINE" | cut -f 1`\t`echo "$LINE" | cut -f 2`")" ]; then
    		if (noteOK) ; then
    			if (timeOK `echo "$LINE" | cut -f 2`) ; then
    				return 0
    			fi
    		fi
    	# First line may specify fix BPM for the music
    	elif [ "$LINE" == "`echo "$LINE" | cut -f 1`" ]; then
    		if [ -z "$BPM" -a -n "$LINE" ]; then
    			setBPM `echo "$LINE" | cut -f 1`
    		fi
    		return 1
    	fi
    	return 2
    }
    
    # Decode node to its specific frequency
    tone() {
    	case "$1" in
    		"AA")	echo "220.0";;
    		"BB"|"HH")	echo "246.9";;
    		"C")	echo "261.6";;
    		"C#")	echo "277.2";;
    		"D")	echo "293.7";;
    		"D#")	echo "311.1";;
    		"E")	echo "329.6";;
    		"F")	echo "349.2";;
    		"F#")	echo "370.0";;
    		"G")	echo "392.0";;
    		"G#")	echo "415.3";;
    		"A")	echo "440.0";;
    		"A#")	echo "466.2";;
    		"B"|"H")	echo "493.9";;
    		"c")	echo "523.2";;
    		"c#")	echo "554.4";;
    		"d")	echo "587.4";;
    		"d#")	echo "622.2";;
    		"e")	echo "659.2";;
    		"f")	echo "698.4";;
    		"f#")	echo "740.0";;
    		"g")	echo "784.0";;
    		"g#")	echo "830.6";;
    		"a")	echo "880.0";;
    		"a#")	echo "932.4";;
    		"b"|"h")	echo "987.8";;
    		# Pauses are at 1 Hz (not hearable)
    		"p"|"P")	echo "1";;
    		*)	echo "$1"
    	esac
    }
    
    # Play a note for a certain time
    play_note() {
    	# Default BPM (if neither specified as argument, nor in music file)
    	setBPM 120
    	BPMS=$((60*1000/$BPM))
    	TONE=$1
    	LENGTH=$2
    	TIME=$(($BPMS*$LENGTH/16))
    
    	beep -f `tone $TONE` -l $TIME
    }
    
    play() {
    	while read LINE; do
    		lineOK "$LINE"
    		if ($?) ; then
    			echo "BPM=$BPM"
    			play_note $LINE
    		fi
    	done < $FILE
    }
    
    if [ -f "$FILE" ]; then
    	setBPM $2
    	play "$FILE"
    else
    	echo -e "ERROR:\tMusic file not found" 1>&2
    fi
     
  4. #3 Remidemi, 21.09.2011
    Remidemi

    Remidemi Routinier

    Dabei seit:
    17.03.2008
    Beiträge:
    352
    Zustimmungen:
    0
    Ort:
    Südpfalz
    Hi Schard!

    Bei deinem letzten Beispiel fehlt, im Gegensatz zum ersten Beispiel, in der Funktion play() das FILE="$1".
    Vielleicht deswegen? Was steht in $1?
     
  5. #4 Gast123, 22.09.2011
    Gast123

    Gast123 Guest

    Hi,

    nee, das ist schon OK.
    Die Variable FILE ist unabhängig von BPM.
    in $1 steht der Pfad zur zu spielenden Musikdatei, in $2 optional die BPM. Beispielsweise:
    Code:
    music ./deckthehalls.mus 110
     
  6. #5 floyd62, 22.09.2011
    floyd62

    floyd62 Routinier

    Dabei seit:
    01.05.2007
    Beiträge:
    309
    Zustimmungen:
    0
    Hi Schard,

    ändere doch einfach mal die play()-Funktion in der ersten Version wie folgt:
    Code:
    play() {
            FILE="$1"
    
            while read LINE; do
                    # if (lineOK "$LINE"); then
                    if lineOK "$LINE" ; then
                            echo "BPM=$BPM"
                            play_note $LINE
                    fi
            done < $FILE
    }
    
    Innerhalb von Klammern führt die Bash Kommandos (im Beispiel also lineOK) in einer Subshell aus; Variablen, die du dort setzt, gelten natürlich nur lokal darin, und werden nicht an die Parent-Shell zurückgegeben.

    Gruss,
    A.
     
  7. #6 Gast123, 24.09.2011
    Gast123

    Gast123 Guest

    Hi floyd,

    genau das war das Problem. Dass das Kommando dann in einer Subshell ausgeführt würde wusste ich nicht. Wieder etwas gelernt.

    Beste Grüße

    Schard
     
  8. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
Thema:

Variableninhalt wird nicht gespeichert

Die Seite wird geladen...

Variableninhalt wird nicht gespeichert - Ähnliche Themen

  1. awk: Dateiinhalt/Variableninhalt als Teil einer if-Anweisung

    awk: Dateiinhalt/Variableninhalt als Teil einer if-Anweisung: Hallo Ich habe folgendes Problem: Anhand dem Ergebnis einer Datenbankabfrage habe ich mir mit sed usw. einen String gebastelt und in einer Datei...
  2. Perl: Variableninhalt "ausfuehren"

    Perl: Variableninhalt "ausfuehren": Hallo, ich habe folgende Frage: Ist es in Perl moeglich, den Inhalt einer Variablen (z.B. ein regulaerer Ausdruck der From /regexp/),...
  3. PATH wird nicht richtig durchsucht

    PATH wird nicht richtig durchsucht: Hi zusammen, ich nutze das Forum schon seit längerem , allerdings hat mir bis jetzt immer die Suchfunktion weitergeholfen. Bei meinem aktuellen...
  4. Suse: Tomas Di Giacomo wird neuer CTO

    Suse: Tomas Di Giacomo wird neuer CTO: Suse hat seinen Vorstand um Dr. Tomas Di Giacomo erweitert, der als Chief Technology Officer ab sofort dem Unternehmen angehört. In der neu...
  5. Edubuntu wird nicht mit Ubuntu 16.04 veröffentlicht

    Edubuntu wird nicht mit Ubuntu 16.04 veröffentlicht: Die Bildungs-Distribution Edubuntu, die zum offiziellen Ubuntu-Veröffentlichungszyklus zählt, wird im April keine neue Version herausgeben. Die...