udev and zenity

Hi,

I cant get it working.
How do I use zenity from udev in Opensuse?
The udev rule is correct and runs the script one time.
But only if I disable the zenity (# before the export DISPLAY parameter and deleting the “|” before zenity starts).

I’m also able to run that script from terminal with zenity.

At the moment I’m really frustated. May you can help me fixing this. this would be aweseome.

I’m pretty sure the problem is because udev is running as root. And root never starts the x server. but why can I run tha script from terminal using sudo? isn’t it the same?

tes.sh script:


#!/bin/bash


export DISPLAY=:0


FILES=/etc/sysconfig/network/ifcfg-eth*
PATH_TO_LOG=/home/admin/Desktop/monitor.log
PATH_TO_ETH_TEMPLATE=/home/admin/Desktop/ifcfg-ethx
MANUFACTURE="Intermec Mobile Computer"
COUNT=0
MAXDEVS=1
FTP_USER=intermec
FTP_PASSWORD=cr52401
PATH_LOCAL_TO=/home/admin/erfassung.txt
FTPLOG=/home/admin/ftplogfile
FTP_SUCCESS_MSG="226 Transfer complete"
MOBILE_IP_START=169.254.2.
MOBILE_IP=""


(
#
# get the correct eth interface 
#


echo "5"; sleep 1
echo "# USB Gerät wird gesucht"; sleep 1




	# check if there the last eth was renamed and save the correct eth number to var
	# mapping to eth55 is set in custom udev rule


	LAST_USB_ETH_VAR=$(dmesg | tail -5 |grep renamed | grep -oe "eth. to eth.." | grep -oe "to eth.." | grep -oe "eth.." | xargs)


	# if it was not renamed check for rndis error


		if   "$LAST_USB_ETH_VAR" == "" ]; then
			LAST_USB_ETH_VAR=$(dmesg | tail -5 | grep "RNDIS init failed"  | grep -oe "-3.")
			echo "Netzwer Interface war nicht ETH55 sondern: $LAST_USB_ETH_VAR" >> $PATH_TO_LOG
			
			if   "$LAST_USB_ETH_VAR" == "-32" ]; then
				echo "RNDIS failed. Skript beendet: $LAST_USB_ETH_VAR" >> $PATH_TO_LOG
				echo "99"; sleep 1
				echo "# Gerät nicht korrekt erkannt. Bitte Gerät trennen, 60 Sekunden warten und erneut verbinden."; sleep 5
				exit
			fi
			
		fi	


	# if it was not renamed check for the last eth number that was registerd


		if   "$LAST_USB_ETH_VAR" == "" ]; then
			LAST_USB_ETH_VAR=$(dmesg | grep register | tail -1 | grep -oe "eth.")
		fi


	#LAST_USB_ETH_VAR=$(dmesg | grep register | tail -1 | grep -oe "eth.")
	echo "letztes Netzwerkinterface von USB Gerät: $LAST_USB_ETH_VAR" >> $PATH_TO_LOG


	echo "20"; sleep 1
	echo "# USB Gerät gefunden auf $LAST_USB_ETH_VAR"; sleep 1
	echo "USB Gerät gefunden auf: $LAST_USB_ETH_VAR" >> $PATH_TO_LOG


	# get if interface ETHxx is up and which IP is configured


	# get IP from ETHxx interface from PC
	IP_AD_PC=$(ip r s | grep $LAST_USB_ETH_VAR | grep -oe "src 169.254.2..." | grep -oe "169.254.2...")


	if   "$IP_AD_PC" == "" ]; then
		echo "25"; sleep 1
		echo "# konfiguriere Netzwerkadapter $LAST_USB_ETH_VAR"; sleep 1
		echo "konfiguriere Netzwerkadapter $LAST_USB_ETH_VAR" >> $PATH_TO_LOG


		cp $PATH_TO_ETH_TEMPLATE /etc/sysconfig/network/ifcfg-$LAST_USB_ETH_VAR


		echo "30"; sleep 1
		echo "# starte Netzwerkadapter $LAST_USB_ETH_VAR"; sleep 1
		echo "starte Netzwerkadapter $LAST_USB_ETH_VAR" >> $PATH_TO_LOG


		rcnetwork restart $LAST_USB_ETH_VAR
		sleep 4
		IP_AD_PC=$(ip r s | grep $LAST_USB_ETH_VAR | grep -oe "src 169.254.2..." | grep -oe "169.254.2...")
	fi
		
	echo "35"; sleep 1
	echo "# Interface ist konfiguriert. Lokale IP ist: $IP_AD_PC"; sleep 10
	echo "Interface ist konfiguriert. Lokale IP ist: $IP_AD_PC" >> $PATH_TO_LOG


#IP_AD_PC=$(ifconfig "$LAST_USB_ETH_VAR" | grep "inet Adresse" | cut -d: -f2 | grep -oe "169.254.2..." | xargs)
#echo "ip schon vorhanden: $IP_AD_PC" >> $PATH_TO_LOG




# getting ip from mobile device


MOBILE_START_END_IP=0




while  ! ping -c 1 $MOBILE_IP_START$MOBILE_START_END_IP;   do
	echo "40"; sleep 1
	echo "# suche MDE auf: $MOBILE_IP_START$MOBILE_START_END_IP"; sleep 1
	echo "suche MDE auf: $MOBILE_IP_START$MOBILE_START_END_IP" >> $PATH_TO_LOG
	let MOBILE_START_END_IP++


	# ignore local eth ip from pinging	
	if  "$MOBILE_IP_START$MOBILE_START_END_IP" == "$IP_AD_PC" ]; then
		let MOBILE_START_END_IP++
	fi
	
	if  "$MOBILE_START_END_IP" == "10" ]; then
		echo "99"; sleep 1
		echo "# IP von MDE nicht gefunden. Bitte Gerät trennen, 60 Sekunden warten und erneut verbinden."; sleep 5
		echo "IP von MDE nicht gefunden. Bitte Gerät trennen, 60 Sekunden warten und erneut verbinden" >> $PATH_TO_LOG
		exit
	fi
done


MOBILE_IP=$MOBILE_IP_START$MOBILE_START_END_IP


echo "60"; sleep 1
echo "# IP vom MDE gefunden: $MOBILE_IP"; sleep 1
echo "IP vom MDE gefunden: $MOBILE_IP" >> $PATH_TO_LOG


echo "70"; sleep 1
echo "# hole Datei"; sleep 1
echo "hole Datei" >> $PATH_TO_LOG


ftp -inv $MOBILE_IP <<! > $FTPLOG
	user $FTP_USER $FTP_PASSWORD
	binary
	cd /Datensammler/Daten
	get Erfassung.txt $PATH_LOCAL_TO
	bye
!
	
	


	if fgrep "$FTP_SUCCESS_MSG" $FTPLOG ; then
		echo "100"; sleep 1
		echo "# Datei wurde nach $PATH_LOCAL_TO übertragen"; sleep 1
		echo "Datei wurde nach $PATH_LOCAL_TO übertragen" >> $PATH_TO_LOG
	else
		echo "99"; sleep 1
		echo "# Übertragung fehlgeschlagen"; sleep 1
		echo "Übertragung fehlgeschlagen" >> $PATH_TO_LOG
		exit
	fi


: "
#count all ethernet interfaces
#COUNT_ETH_INT=$(find /etc/sysconfig/network -type f -name "ifcfg-eth*" | wc -l)


echo "aktuelle Anzahl ETH Geräte: $COUNT_ETH_INT" >> $PATH_TO_LOG


# checks if there are more than $MAXDEVS Intermec devices connected
# but only if there are network interfaces


if  $COUNT_ETH_INT -gt 0 ]; then


	for f in $FILES
	do
		source $f
			if   "$NAME" == "$MANUFACTURE" ]; then
			COUNT=$(($COUNT +1))
			fi
	done


	echo "bereits verbundene Geräte von Intermec/Honeywell: $COUNT" >> $PATH_TO_LOG


else
	cp $PATH_TO_ETH_TEMPLATE /etc/sysconfig/network/ifcfg-$LAST_USB_ETH_VARB
	ifup $COUNT_ETH_INT
	echo "$COUNT_ETH_INT wurde konfiguriert und gestartet" >> $PATH_TO_LOG
	


fi


#if  $COUNT > $MAXDEVS ]; then
#fi


"
) |
zenity --progress \
	-- title="Update System Log" \
	--text="scanning "\
	--percentage=0 


if  "$?" = -1 ]; then
	zenity --error \
	--text="failed"
fi
exit 0

test.rules

SUBSYSTEM=="usb", ATTR{idVendor}=="067e", ATTR{idProduct}=="1003", ATTR{serial}=="0040056a-0e9d-0801-1240-01060000d201", ACTION=="add", RUN+="/usr/test.sh"


I have no idea what zenity is or is supposed to do. So the following can be complete gibberish.

I see yoou use the environment variable DISPLAY. Thus I assume that you want to do something on the X display that you configure there.

Are you sure that
a) there is such a display active;
b) the user owning that display has granted permission to do actions on his/her display (e.g. using xhosts)?

I’m using zenity to get the user some feeback about the progress of the script.
My script is setting up a eth interface and gets a file from ftp. After that it should inform the user that the file was transfered correct.

Do you have a better idea? Thought it is a very simple way to creat a very small gui for my script.

of course the display is active.
As I mentioned I can run the exact same script from terminal using sudo.

to b)
the user is root or who is running the script when I start it with udev? Therefore it shouldn’t be a problem with permission.

yes, but then you run it from “within” the display/session, which would grant you access in the same way that other GUI applications that you start from the same session will be granted access. IMHO it is exactly what you experiencce.

As it is NOT started from within the session, there is NOT automatic access granted. And that has nothing to do with who the process owner is. It is not file permissions!

The background is that X is a network server. Thus it is not that strange that there is some mechanism to (dis)allow users from (other) systems to e.g. access your display, opening windows at will and worse, capture what you type on the keyboard

See

man Xserver

under GRANTING ACCESS.

Asimple way to configure access is using xhost. I see that it is not installed by default on my openSUSE 13.2, but it is a package on the OSS repo. Installing will also install it’s man page.

First,
It always helps to post in a correct Forum. IMO your topic has almost nothing and possibly absolutely nothing to do with hardware.
Then, it’s always useful to verify that your application (zenity in this case, but possibly identifying the others like your FTP app) come from the OSS and not elsewhere, and possibly whether you have the latest versions of these apps installed (if you don’t know, then post the app version numbers).

Never having used zenity before,

I still took a quick look at how zenity works.
Based on the official docs at
https://help.gnome.org/users/zenity/stable/

  1. You didn’t post your zenity script. Your base script doesn’t include any zenity commands. If your “test.rules” is some kind of script and intended to be placed somewhere in your init tree, I don’t think that’s the recommended or proper way to implement your script (or prove me wrong by citing the reference your implementation is based on)

  2. You didn’t post your reference for creating your zenity script. The following is the official zenity documentation for creating “Progress” scripts. Note that if your base script runs before the User has logged in, you don’t want to run a “Progress” script, maybe a “Notification” script.
    https://help.gnome.org/users/zenity/stable/progress.html.en

  3. It might help to describe what you’re trying to display to the User. Your posted script looks like it sets up a connection to an FTP server. I don’t know what this has to do with udev, and maybe this is partly basic to why you’re not getting desired results (not understanding what you’re working with?)

You might need to provide a detailed description of what you are trying to do, what you posted doesn’t provide a clear picture to me.

TSU

@hcvv
ah, got it.
But shouldn’t it be also possible to use the .xauthority file? I’ve some examples on other sites. They used a .Xauthority file from the user that should get the notfication on his xserver.

@tsu2,

thank you. Ok, the Hardware Forum might not be the best Forum for this. But it includes peripheral. And udev is used for peripheral. But I understand what you mean.

I’m pretty sure I posted the zenity code too :). It is the last block of the script.

for testing it would also be enough to use only this Code in a script file. Same here.

zenity --info --text="test"

there is no ftp or anything else needed. I just copied the complete script. might not be the best way.

xhosts manipulatees the xauthoroty file IIRC. In any case there are several methods, I only wanted to point you to the general idea of xserver security.

BTW, re the other discussion, it is you that decided to post here in hardware. That means that you choose your audience.

Yes,
For some reason when I did a search on the “zenity” command it came up empty but you definitely have it there at the end of your script.

Reading your script again,
I still think that it goes through a number of steps testing network components, then does some network connectivity tests and finishes testing FTP connectivity…

Something else you might consider if the prerequisites for zenity aren’t yet up and running by the time zenity needs them… Have you considered popping up a console instead using something like dialog (you can view the code for the “Gauge meter” for a progress bar.
http://www.unixcl.com/2009/12/linux-dialog-utility-short-tutorial.html

TSU

Hi,

Thats quite a long grep pipline :), I have one suggestion on the eth part which is commented. In a Linux system there is a /sys directory for the nics and since you’re using bash make use of an array and just parse it e.g.

shopt -s nullglob
netifs=(/sys/class/net/eth*); printf '%s
' "${netifs@]}"
shopt -u nullglob

And to count how many eth* devices

printf '%s
' "${#netifs@]}"

To add that to the test

if (( ${#netifs@]} )); then
  printf '%s
' "eth has ${#netifs@]} nics."
fi

netifs is arbitrary like any variable name. Good luck…