Shell Skript unter Lubuntu zum Monitorwechsel

0815burner

Commander
Registriert
Nov. 2006
Beiträge
2.689
H,

ich nutze Lubuntu und bin fleißig am "Individualisieren". Nun habe ich einen tolles Skript gefunden, das auch bei mir funktioniert:

http://sgaul.de/2011/08/20/zwischen-monitor-und-fernseher-hin-und-herschalten/

Nun dachte ich mir, ändere ich die Funktion ab, so dass entweder beide Monitore an sind (Erweitert, extern ist links von Intern) oder eben nur der Externe läuft. Das Ziel zu definieren war ja noch einfach;-)

Jetzt habe ich ein wenig gelesen, kam aber nicht weiter, da ich vieles nicht verstehe..

Im Moment ist das mein Stand, der aber nicht funktioniert:
Code:
#!/bin/bash
EXTERNAL_OUTPUT="VGA1"
INTERNAL_OUTPUT="LVDS1"


X_USER=$(w -h -s | grep ":[0-9]\W" | head -1 | awk '{print $1}')
export DISPLAY=$(w -h -s | grep ":[0-9]\W" | head -1 | awk '{print $3}')

# Switch to X user if necessary
if [ "$X_USER" != "$USER" ]; then
       SU="su $X_USER -c"
else
       SU="sh -c"
fi

#INTERNAL_STATE=$($SU xrandr | grep ^$INTERNAL_OUTPUT | grep " con" | sed "s/.*connected//" | sed "s/ //" | sed "s/ .*//g"| sed "s/(normal//g" )
#EXTERNAL_STATE=$($SU xrandr | grep ^$EXTERNAL_OUTPUT | grep " con" | sed "s/.*connected//" | sed "s/ //" | sed "s/ .*//g"| sed "s/(normal//g" )

if 	[ xrandr | grep 'LVDS1 connected' ]; then
		INTERNAL_STATE=True
elif 	[xrandr | grep 'LVDS1 connected'  ]; then
		INTERNAL_STATE=False
else 	echo "Bearbeitungsfehler"

fi

echo "Umschaltbedingung: $INTERNAL_STATE"


if [  INTERNAL_STATE==1 ]; then
	echo "2 Monitorbetrieb"
	xrandr --output $EXTERNAL_OUTPUT --auto --left-of $INTERNAL_OUTPUT --output $INTERNAL_OUTPUT --auto	
elif [  INTERNAL_STATE==0  ]; then
	echo "1 Monitorbetrieb"
	xrandr --output $EXTERNAL_OUTPUT --auto --output $INTERNAL_OUTPUT --off
fi

Ich möchte die Funktion xrandr ausführen und dort den Zustand des externen Monitors auslesen. Dementsprechend will ich dann die Monitore schalten. Die variable Namensübergabe der Monitore habe ich in der IF-Anweisung weggelassen zwecks Fehlervermeidung.

Vielleicht kann mir jmd. auch die ersten beiden If-Anweisungen erläutern: Die erste liest doch "nur" den Nutzernamen aus, sodass ich später einen Befehl ausführen kann innerhab der Bedingung?
Quasi so:
-> ($SU xrandr | grep ^$INTERNAL_OUTPUT...

Die zweite (ausgeklammerte) liest den Zusatnd, aber was machen die ganzen sed-Anweisungen??
Im sehr guten ubuntuuser-Wiki wurde ich in diesem Fall leider nicht schlauer/ schlau genug.

Danke schon mal fürs lesen und vielleicht sogar für die Hilfe!
 
Hi,

ich nehme zum Konfigurieren ArandR. Das kann Konfigurationen als Skript speichern.
Dann kommt sowas raus:
Code:
#!/bin/sh
xrandr --output VGA-0 --off --output DVI-0 --mode 1920x1200 --pos 0x0 --rotate normal --output HDMI-0 --mode 1280x1024 --pos 1920x177 --rotate normal
Da kann man zwei Skripte abspeichern und nach Bedarf ausführen.

Zurück zum Skript:
die Zeile 21 muss wohl lauten:
Code:
elif 	[xrandr | grep 'VGA1 connected'  ]; then

Ich würde das so machen:
Code:
elif 	[xrandr | grep 'VGA1' | grep  'connected'  ]; then
Dann braucht man nicht auf Leerzeichen zu achten. Wie in Zeile 17.

Zeilen 6 und 7.
Code:
w -h -s
gibt bei mir aus:
Code:
root     tty1       1:41m -bash
user       pts/0     16:51m /usr/bin/evilvte
user       pts/1      1.00s w -h -s
Code:
who  -s
root     tty1         2016-02-20 22:17
user       pts/0        2016-02-20 22:23 (:0)
user       pts/1        2016-02-20 22:23 (:0)

Ich denke das Zweite ist gewollt. Es kann sein, dass unter Ubuntu das Erste auch funktioniert.
Dann enthält X_USER den Nutzernamen.
In der Zeile 10 wird geprüft, ob der derzeitige Nutzer der ist, der den X-Server gestartet hat. Wenn nicht, wird der Nutzer gewechselt.

Sed dient zum Bearbeiten von Strings mittels regulärer Ausdrücke.

Beispiel:

Code:
xrandr | grep HDMI-0 | grep connected
HDMI-0 connected primary 1920x1200+0+0 (normal left inverted right x axis y axis) 550mm x 344mm

Mit sed:

Code:
xrandr | grep HDMI-0 | grep connected | sed "s/.*connected//" 
 primary 1920x1200+0+0 (normal left inverted right x axis y axis) 550mm x 344mm

Code:
s/.*connected//

Sucht nach beliebigen Zeichen (".*") und "connected" und ersetzt sie durch nichts.

Code:
sed "s/ //"

Sucht nach Leerzeichen und ersetzt sie durch nichts.

https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck
 
Super das du mir so hilfst!

ich programmiere normalerweise PLCs von Siemens, da ist das hier doch schon sehr verschieden!

ich gehe morgen das Ganze durch und werde berichten.

Noch was zum Verständnis: Das Pipe-Zeichen in der If-Anweisung verknüpft doch die Befehle soweit ich weiß.
Wenn ich jetzt die grep Befehle auftrenne so wie du vorschlägst
Code:
elif 	[xrandr | grep 'VGA1' | grep  'connected'  ]; then
wird die Bedingung doch immer wahr, da xrandr bei mir folgendes ausgibt:
Code:
Screen 0: minimum 8 x 8, current 1280 x 1024, maximum 32767 x 32767
LVDS1 connected (normal left inverted right x axis y axis)
   1366x768      59.59 +
   1360x768      59.80    59.96  
   1280x720      60.00  
   1024x768      60.00  
   1024x576      60.00  
   960x540       60.00  
   800x600       60.32    56.25  
   864x486       60.00  
   640x480       59.94  
   720x405       60.00  
   680x384       60.00  
   640x360       60.00  
DP1 disconnected (normal left inverted right x axis y axis)
DP2 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
VGA1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
   1280x1024     60.02*+  75.02  
   1152x864      75.00  
   1024x768      75.08    75.03    60.00  
   832x624       74.55  
   800x600       75.00    60.32  
   640x480       75.00    60.00  
   720x400       70.08  
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
Bitte nicht über die alte HW lachen, ich habe ein Problem damit funktionierende Sachen wegzuschmeißen (und auch mit Dingen die nicht lange halten:-)). Insofern bin ich damit zufrieden.

Oder kann ich darauf prüfen, das beide Ausdrucke in einer Zeile stehen?
Ergänzung ()

So, ich hatte da noch einige Probleme , gehen tut es aber noch nicht.

Zuerst zeigt mir xrandr immer "LVDS1 connected" an, egal ob der interne Monitor an oder aus ist. Diese Abfrage habe ich geändert und im Moment diesen Code:
Code:
#!/bin/bash
EXTERNAL_OUTPUT="VGA1"
INTERNAL_OUTPUT="LVDS1"
MonON="Start"

X_USER=$(w -h -s | grep ":[0-9]\W" | head -1 | awk '{print $1}')
export DISPLAY=$(w -h -s | grep ":[0-9]\W" | head -1 | awk '{print $3}')

# Switch to X user if necessary
if [ "$X_USER" != "$USER" ]; then
       SU="su $X_USER -c"
else
       SU="sh -c"
fi

#INTERNAL_STATE=$($SU xrandr | grep ^$INTERNAL_OUTPUT | grep " con" | sed "s/.*connected//" | sed "s/ //" | sed "s/ .*//g"| sed "s/(normal//g" )
#EXTERNAL_STATE=$($SU xrandr | grep ^$EXTERNAL_OUTPUT | grep " con" | sed "s/.*connected//" | sed "s/ //" | sed "s/ .*//g"| sed "s/(normal//g" )

if 	[ $($SU xrandr | grep "LVDS1 connected (normal left inverted right x axis y axis)" )]; then
		MonON="True"
elif 	[ $($SU xrandr | grep "LVDS1 connected 1366x768" )]; then
		MonON="False"
else 	echo "Bearbeitungsfehler"

fi

	echo "Umschaltbedingung MonON:" $MonON 


if   [  MonON == 'True' ]; then
		echo "2 Monitorbetrieb!"
		xrandr --output $EXTERNAL_OUTPUT --auto --left-of $INTERNAL_OUTPUT --output $INTERNAL_OUTPUT --auto	
elif [  MonON == 'False'  ]; then
		echo "1 Monitorbetrieb"
		xrandr --output $EXTERNAL_OUTPUT --auto --output $INTERNAL_OUTPUT --off
else 		echo "Hier geht was nicht!"
fi

Als Rückgabe bekomme ich das hier:

Code:
./Mon_umschalten.sh: Zeile 19: [: Fehlende »]«
Bearbeitungsfehler
Umschaltbedingung MonON: Start
Hier geht was nicht!

Funktion ist gleich Null, immer mal wieder habe ich aber einen Stand, das der interne Monitor immer an oder immer aus geht. Hilfe!

Auch musste ich die Variable MonOn als String beschreiben, da ich leider nicht wußte wie das binär geht;-). So habe ich aber einen Startwert und sehe, das nichts passiert..
 
Zuletzt bearbeitet:
Gut funktionierende Hardware weiterzuverwenden ist löblich. :)

Code:
elif 	[xrandr | grep 'VGA1' | grep  'connected'  ]; then

Stimmt, bei "disconnected" greift das auch, hab ich nicht bedacht.

Also entweder wie gehabt

Code:
elif 	[xrandr | grep 'VGA1 connected'  ]; then

oder

Code:
elif 	[xrandr | grep 'VGA1' | grep  ' connected'  ]; then

LVDS ist auch immer dran. Display ist immer per Flachbandkabel angeschlossen. Du kannst nur dem Graphikchip sagen, dass er keine Ausgabe drauf machen soll.

Kannst du nochmal genau beschreiben, was du genau machen willst?

Gibt es nur zwei Zustände?
Code:
LVDS1 und 
LVDS1 + VGA1?
Also wenn VGA dran ist dann 2., sonst 1.?

ich würde die grep-Ausdrücke in kleinen Häppchen in Kommandozeile testen.

Also

Code:
xrandr | grep "LVDS1 connected"
und Ergebnis anschauen.

Dann
Code:
xrandr | grep "LVDS1 connected" | grep " 1366x768"
 
Zuletzt bearbeitet:
Hi,
ich möchte folgendes:

Mein Laptop wird mittlerweile zu 99,9% nur noch stationär eingesetzt, das heist der VGA1 ist immer angeschlossen.
Meistens reicht es mir nur mit dem externen Monitor zu arbeiten. In Ausnahmefällen will ich den internen dazu schalten um zum Beispiel Sat over IP zu nutzen (auf gut deutsch nebenher Fernseh gucken).

Bisher habe ich dann immer über die Einstellungen den internen Monitor umgestellt, das hier wäre aber über Button/Hardwaretaste viel komfortabler. Ausserdem hätte ich wieder was dazu gelernt.

Jetzt wollte ich anhand des Zustandes des internen Monitors abfragen ob er an oder aus ist. Das kann ich über den Text der Auflösung (1366x766) machen, da dieser beim ausgeschalteten Monitor nicht ausgegeben wird.

Augenscheinlich funktioniert aber meine gesamte If-Anweisung nicht, da immer 'Bearbeitungsfehler' auftaucht und meine Hilfsvariable den Startwert 'Start' behält..

Zum Verständnis kann ich heute (oder morgen, habe heute noch Termine) mal die unterschiedlichen xrandr Ausgaben mit und ohne internen Monitor hier posten, vllt. wird es dann noch klarer.

Danke und bis dann.

So, xrandr mit ausgeschaltetem internen Monitor:
Code:
Screen 0: minimum 8 x 8, current 1280 x 1024, maximum 32767 x 32767
LVDS1 connected (normal left inverted right x axis y axis)
   1366x768      59.59 +
   1360x768      59.80    59.96  
   1280x720      60.00  
   1024x768      60.00  
   1024x576      60.00  
   960x540       60.00  
   800x600       60.32    56.25  
   864x486       60.00  
   640x480       59.94  
   720x405       60.00  
   680x384       60.00  
   640x360       60.00  
DP1 disconnected (normal left inverted right x axis y axis)
DP2 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
VGA1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
   1280x1024     60.02*+  75.02  
   1152x864      75.00  
   1024x768      75.08    75.03    60.00  
   832x624       74.55  
   800x600       75.00    60.32  
   640x480       75.00    60.00  
   720x400       70.08  
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

xrandr mit eingeschaltetem internen Monitor:
Code:
Screen 0: minimum 8 x 8, current 2646 x 1024, maximum 32767 x 32767
LVDS1 connected 1366x768+1280+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1366x768      59.59*+
   1360x768      59.80    59.96  
   1280x720      60.00  
   1024x768      60.00  
   1024x576      60.00  
   960x540       60.00  
   800x600       60.32    56.25  
   864x486       60.00  
   640x480       59.94  
   720x405       60.00  
   680x384       60.00  
   640x360       60.00  
DP1 disconnected (normal left inverted right x axis y axis)
DP2 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
VGA1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
   1280x1024     60.02*+  75.02  
   1152x864      75.00  
   1024x768      75.08    75.03    60.00  
   832x624       74.55  
   800x600       75.00    60.32  
   640x480       75.00    60.00  
   720x400       70.08  
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

Der Unterschied in der LVDS1 Zeile ist glaube ich erkennbar.
 
Zuletzt bearbeitet: (Ergänzung)
so., nach langer Pause habe ich mich noch mal hier dran gemacht und es hinbekommen! Vielleicht hilft es jemanden, auch wenn es nicht perfekt ist! Ein paar Leichen sind noch drin.

Code:
#!/bin/bash
EXTERNAL_OUTPUT="VGA1"
INTERNAL_OUTPUT="LVDS1"
MonON="Start"

X_USER=$(w -h -s | grep ":[0-9]\W" | head -1 | awk '{print $1}')
export DISPLAY=$(w -h -s | grep ":[0-9]\W" | head -1 | awk '{print $3}')

# Switch to X user if necessary
if [ "$X_USER" != "$USER" ]; then
       SU="su $X_USER -c"
else
       SU="sh -c"
fi

#INTERNAL_STATE=$($SU xrandr | grep ^$INTERNAL_OUTPUT | grep " con" | sed "s/.*connected//" | sed "s/ //" | sed "s/ .*//g"| sed "s/(normal//g" )
#EXTERNAL_STATE=$($SU xrandr | grep ^$EXTERNAL_OUTPUT | grep " con" | sed "s/.*connected//" | sed "s/ //" | sed "s/ .*//g"| sed "s/(normal//g" )

if 	$SU xrandr | grep "LVDS1 connected (normal left inverted right x axis y axis)" ; then
		MonON="False"
elif 	$SU xrandr | grep "LVDS1 connected 1366x768" ; then
		MonON="True"
else 	echo "Bearbeitungsfehler"

fi
	echo "Umschaltbedingung MonON:" $MonON 


if   [[ $MonON = "True" ]] ; then
		echo "1 Monitorbetrieb"
		xrandr --output $EXTERNAL_OUTPUT --auto --output $INTERNAL_OUTPUT --off
		
else   		echo "2 Monitorbetrieb!"
		xrandr --output $EXTERNAL_OUTPUT --auto --left-of $INTERNAL_OUTPUT --output $INTERNAL_OUTPUT --auto

fi

Dazu habe ich mir auch noch die passende .Desktop Datei erstellt;-)

Code:
[Desktop Entry]
Name=Monitor umschalten
Comment=Wechsel zwischen Monitorberieb "nur Extern" oder "Extern plus intern"
Keywords=Monitor;umschlaten;
Exec=bash "/usr/share/Monitor umschalten/Mon_umschalten.sh"
Icon=/usr/share/Monitor umschalten/Monitorumschalten_Symbol64.png
Terminal=false
Type=Application
Categories=GNOME;GTK;Utility;
#X-GNOME-Bugzilla-Bugzilla=GNOME
#X-GNOME-Bugzilla-Product=gucharmap
#X-GNOME-Bugzilla-Component=general
#X-GNOME-Bugzilla-Version=3.18.0
StartupNotify=true
#X-Ubuntu-Gettext-Domain=gucharmap
Name[de_DE]=Monitor umschalten

Vielleicht kann es ja mal jmd brauchen!
 
Zurück
Oben