ubuntuusers.de

Rechnen in Bash

Status: Ungelöst | Ubuntu-Version: Ubuntu MATE 22.04 (Jammy Jellyfish)
Antworten |

jochenv

Anmeldungsdatum:
23. April 2016

Beiträge: 670

Wohnort: Kurhessen

Hallo zusammen

habe kleines Problem mit dem rechnen in der Bash ....

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/bash

#echo 100 | sudo tee /sys/class/backlight/radeon_bl0/brightness

typeset -i wert

file='/sys/class/backlight/radeon_bl0/brightness'
while read wert; do
echo "Das ist der Wert..........: "$wert
done < $file

let wert=$wert+8
echo "Das ist der Wert plus acht: "$wert

echo $wert | sudo tee /sys/class/backlight/radeon_bl0/brightness

in Zeile 12 sollen 8 dazu addiert werten und das funktioniert nicht ... was mach ich falsch ?

Gruß Jochen

Axel-Erfurt

Anmeldungsdatum:
18. Mai 2016

Beiträge: 1347

vielleicht

wert=$(($wert+8))

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

Das Problem entsteht durch die while-Schleife, weil die in einer Subshell ausgeführt wird und damit die Variable wert nicht nach außen gelangt - wofür ist die überhaupt nötig?

Ich würde da lieber eine Arithmetic Expansion nutzen:

1
2
3
4
5
file='/sys/class/backlight/radeon_bl0/brightness'
declare -i wert=$(<"$file")
echo "Das ist der Wert..........: ${wert}"
echo -n "Das ist der Wert plus acht: "
echo $(( wert + 8 )) | sudo tee /sys/class/backlight/radeon_bl0/brightness

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13207

seahawk1986 schrieb:

Das Problem entsteht durch die while-Schleife, weil die in einer Subshell ausgeführt wird

Wo ist da eine Subshell?

Es geht übrigens auch

1
2
wert=$((wert + 8)) # ohne $ in der Klammer
: $(( wert += 8 )) # nur bash, nicht sh

jochenv

(Themenstarter)

Anmeldungsdatum:
23. April 2016

Beiträge: 670

Wohnort: Kurhessen

seahawk1986 schrieb:

Das Problem entsteht durch die while-Schleife, weil die in einer Subshell ausgeführt wird und damit die Variable wert nicht nach außen gelangt - wofür ist die überhaupt nötig?

Ich würde da lieber eine Arithmetic Expansion nutzen:

1
2
3
4
5
file='/sys/class/backlight/radeon_bl0/brightness'
declare -i wert=$(<"$file")
echo "Das ist der Wert..........: ${wert}"
echo -n "Das ist der Wert plus acht: "
echo $(( wert + 8 )) | sudo tee /sys/class/backlight/radeon_bl0/brightness

Das funktioniert. Jedoch ausschließlich in der Bash. Als Bash für eine Tastatenkombination funktioniert es nicht und auf dem "Schreibtisch" als "Startes" funktioniert es auch nicht. Vermute das es an dem sudo bein schreiben der Datei liegt.

Gruß Jochen

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9717

Wohnort: Münster

rklm schrieb:

seahawk1986 schrieb:

Das Problem entsteht durch die while-Schleife, weil die in einer Subshell ausgeführt wird

Wo ist da eine Subshell?

In der Shell ist jede Schleife eine Subshell, da hat seahawk1986 schon recht.

Es geht übrigens auch […]

schöner, weil mit herkömmlicher, breiter bekannter Syntax:

#!/bin/bash
file='/sys/class/backlight/radeon_bl0/brightness'
declare -i wert ; read wert < "$file"
wert+=8
echo $wert | sudo tee "$file"

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13207

kB schrieb:

rklm schrieb:

seahawk1986 schrieb:

Das Problem entsteht durch die while-Schleife, weil die in einer Subshell ausgeführt wird

Wo ist da eine Subshell?

In der Shell ist jede Schleife eine Subshell, da hat seahawk1986 schon recht.

Das sehe ich anders.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ cat x
#!/bin/sh

unset foo
c=1

while [ $c -gt 0 ]; do
  foo=bar
  c=0
done

echo ">> $foo"

$ sh x
>> bar

schöner, weil mit herkömmlicher, breiter bekannter Syntax:

Ich bevorzuge für Skripte die sh, solange es nicht zu umständlich wird oder Features (meist Arrays) fehlen.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

Es hängt wohl an der Kombination aus Loop und Pipeline/Umleitung und der verwendeten Shell: https://mywiki.wooledge.org/BashFAQ/024

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13207

seahawk1986 schrieb:

Es hängt wohl an der Kombination aus Loop und Pipeline/Umleitung und der verwendeten Shell: https://mywiki.wooledge.org/BashFAQ/024

Das Beispiel dort nutzt ja auch eindeutig die Schleife in einer Pipe. Das ist standardmäßig natürlich immer eine Subshell. Die Bash kann über shopt -s lastpipe so eingestellt werden, dass sie selbst den letzten Befehl in einer Pipeline ausführt. Die ksh macht das anscheinend sowieso. Aber der Code im ersten Posting enthält nichts dergleichen. Da wird lediglich die Eingabe umgeleitet. Das führt nicht zu einer neue Subshell, wie man leicht mit meinem Beispiel um die Umleitung ergänzt sehen kann.

Keinesfalls ist diese Aussage wahr:

kB schrieb:

In der Shell ist jede Schleife eine Subshell, da hat seahawk1986 schon recht.

Jedenfalls nicht, ohne zu erwähnen, um welche Shell es sich handelt. Die Manpage der Heirloom (?) Shell behauptet jedenfalls, dass das dort bei Umleitungen passiert:

If a command other than a simple-command (i.e. 'for ...', 'case ...' etc.) is redirected, it is executed in a subshell.

Das ergibt für mich allerdings keinen Sinn, weil eine simple Umleitung gar keine Notwendigkeit für einen separaten Prozess hat - anders als bei einer Pipeline. Anscheinend war das mal so und vermutlich will das (jetzt auch schon lange eingeschlafene) Projekt Heirloom obsolete - nein: "traditionelle" Implementierungen zur Verfügung stellen. http://heirloom.sourceforge.net/

Ich kann mir vorstellen, dass frühe Versionen der sh eine Subshell bei Umleitungen gestartet haben, weil dann der Dateideskriptor nicht geschlossen werden muss, sondern einfach mit der Shell zusammen stirbt - also Faulheit Optimierung bei der Implementierung.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Wieso überhaupt in einer Schleife - haben manche Brightnessfiles mehr als eine Zeile?

1
echo $(( $(< /sys/class/backlight/intel*/br*) + 8)) 

(auf meine Hardware adaptiert)

Antworten |