LINUX.ORG.RU

festival + udev


0

0

есть замечательная статья как заставить festival озвучивать подключаемые устройства http://www.linux.org.ru/wiki/en/Udev_festival но с появлением нового udev статья стала неактуальна. я обновился с убунту 8.10 до 9.10 и скрипт перестал работать. помогите пожалуйста его адаптировать к новому udev


Ответ на: комментарий от Unclown

просто замолчал. а ошибки как показать? при запуске из терминала просто тишина.

ratte
() автор топика
Ответ на: комментарий от Unclown

извиняюсь, затормозил :0 так вот- в новой версии udev команды udevinfo нет, вместо нее udevadm info . и аргументы соответственно изменилиаь,так вот мне не разобраться как подправить скрипт под новый вариант.

ratte
() автор топика
Ответ на: комментарий от ratte

то есть проблема только в

function get_device_attr ()
{
	path=`find /sys/devices -name $1`
	echo `$UDEVINFO -a -p $path | grep $2 | cut -f 2 -d '"'`
}

или есть еще какие-то грабли?

Unclown
()
Ответ на: комментарий от Unclown

я думаю только здесь, но так как не силен (вернее-вообще дятел) в скриптах, то сам починить не смог

ratte
() автор топика
Ответ на: комментарий от ratte

ты лгешь

слушай а разве в убунте udevinfo выпилили уже? в fc12 все на месте еще. вопрос в другом, что этот скрипт выдавал на выходе? то есть какие слова произносил?

Unclown
()
Ответ на: ты лгешь от Unclown

udevinfo выпилен. «$name» «was found»-говорило для флэшек

«device» «has been removed»-говорило для флэшек

«$name» «was changed»- говорило для cdrom

$name - то , что отображается в названии устройства при подключении (на раб. столе) device - уже не помню, ибо сменил на произвольную фразу,

ratte
() автор топика
Ответ на: комментарий от Unclown

до это го то я сам догадался, но как вывести это имя на фестиваль? и вот строка path=`find /sys/devices -name $1 и соответствие этому- --path=$path мучает меня сомнение

ratte
() автор топика
Ответ на: комментарий от ratte

ты $name получил? дальше все должно нормально выдаваться. у меня что на центосе, что в федоре product в выдаче udevinfo нет. а флешки в /sys/devices торчат, тут как раз все нормально

Unclown
()
Ответ на: комментарий от ratte

в смыле доставь сюда выхлоп

udevadm info --attribute-walk --path=/sys/block/sdb | grep product и

udevadm info --attribute-walk --path=/sys/block/sdb | grep media

Unclown
()
Ответ на: комментарий от ratte

в 62-festival.rules стоит заменить %b на %k в случае

UBSYSTEMS=="usb"

Для блочных устройств

grep media
не выводит ничего разумного по-этому заменил media на KERNEL чтоб выводилось его имя. Попробуй исправленный скрипт на вики.

kim-roader ★★
()
Ответ на: комментарий от kim-roader

спасибо! всё теперь работает и я немного въехал что к чему, вот только он по три раза отчего-то повторяет теперь :) видать намолчался гад , а теперь за всё время молчания наговаривается.

ratte
() автор топика
Ответ на: комментарий от ratte

решил это удалением строк    echo «optical drive»       ;;       [sh]d*) все стало нормально определять и произносить один раз вместо пяти. Unclown, kim-roader спасибо.

ratte
() автор топика
Ответ на: комментарий от ratte

проблема в том сколько udev выдает сообщений. Как вариант отключить вывод либо для usb, либо для блочных устройств. или создать в /var/ файл c базой подключенных устройств. Второй вариант, наверно, попробую сделать вечером

kim-roader ★★
()
Ответ на: комментарий от psv1967

Получилось, но можно сделать код и получше. Ну знаю стоит ли это в вики класть, так что бери тут:

#!/bin/bash

export PATH=/bin:/sbin:/usr/bin:/usr/sbin

FESTIVAL="festival --tts"

DEVICE=$1
UDEVINFO="udevadm info"
BD="/tmp/devs"

[ -z "$DEVICE" ] && exit
[ -z "$ACTION" ] && exit

function get_device_attr ()
{
	path=`find /sys/devices -name $1`
	echo `$UDEVINFO --attribute-walk   --path=$path | grep $2 -m1 | cut -f 2 -d '"'`
}

function get_device_name ()
{
	device=$1

	case $device in
		[0-9]-[0-9])
			s=`get_device_attr $device "product"`
			[ -z "$s" ] && echo "device" || echo "$s"		
		;;
		sr*)
			echo "optical drive"
		;;
		[sh]d*)
			s=`get_device_attr $device "KERNEL"`
			echo "$s drive"
		;;
		*)
			exit 1
		;;
	esac
	
}
function say ()
{
	echo "$1 $2" | $FESTIVAL
	exit
}

function get_devices ()
{
	path=`find /sys/devices -name $1`
	$UDEVINFO --attribute-walk   --path=$path | grep -e 'looking at \(parent \)\?device' | cut -f2 -d\' \
		| awk '{ lines = lines " " $0 } END {print lines}'
}
function add_device ()
{
	devs=`get_devices $1`
	if [ -s $BD ]; then
		cat /tmp/devs | awk "BEGIN { fnd=0 } 
		                    {
		                      if ( index(\$0, \"$devs\") ) { fnd=1; print \$0 }
		                      else if ( index(\"$devs\", \$0) ) { fnd=1; print \"$devs\" }
		                      else { print \$0 }
		                    }
		                    END { exit fnd }" > /tmp/$$.tmp
		if (( $? )); then
			mv /tmp/$$.tmp $BD
			exit 1
		else
			rm /tmp/$$.tmp
			echo $devs >> $BD
			exit 0
		fi
	else
		echo $devs > $BD
		exit 0
	fi
}
function remove_device ()
{
	if ( grep "$1" /tmp/devs ); then
		sed -i "/$1/ d" /tmp/devs
		exit 0
	else
		exit 1
	fi
}

name=`get_device_name $DEVICE`
[ $? != 0 ] && exit # если девайс не соответствует отслеживаемым нами то сразу выходим

if [ -n "$name" ]; then 
	case "$ACTION" in
		add)
		add_device "$DEVICE" || exit
		say "$name" "was found"
		;;
		remove)
		remove_device "$DEVICE" || exit
		say "device" "has been removed"		
		;;
		change)
		say "$name" "was changed"
		;;
	esac
fi

В $BD ведется база подключенных девайсов. Также, возможно, не стоит отправлять в $BD самую длинную цепочку девайсов, а вместо это оставлять первую прилетевшую.

kim-roader ★★
()
Ответ на: комментарий от psv1967

Получилось, но можно сделать код и получше. Ну знаю стоит ли это в вики класть, так что бери тут:

#!/bin/bash

export PATH=/bin:/sbin:/usr/bin:/usr/sbin

FESTIVAL="festival --tts"

DEVICE=$1
UDEVINFO="udevadm info"
BD="/tmp/devs"

[ -z "$DEVICE" ] && exit
[ -z "$ACTION" ] && exit

function get_device_attr () 
{
   path=`find /sys/devices -name $1`
   echo `$UDEVINFO --attribute-walk   --path=$path | grep $2 -m1 | cut -f 2 -d '"'` 
}

function get_device_name () 
{
   device=$1

   case $device in
      [0-9]-[0-9])
         s=`get_device_attr $device "product"`
         [ -z "$s" ] && echo "device" || echo "$s"       
      ;;
      sr*)
         echo "optical drive" 
      ;;
      [sh]d*)
         s=`get_device_attr $device "KERNEL"`
         echo "$s drive" 
      ;;
      *)
         exit
      ;;
   esac
}
function say () 
{
   echo "$1 $2" | $FESTIVAL
   exit
}

function get_devices () 
{
   path=`find /sys/devices -name $1`
   $UDEVINFO --attribute-walk   --path=$path | grep -e 'looking at \(parent \)\?device' | cut -f2 -d\' \
           | awk '{ lines = lines " " $0 } END {print lines}'
}
function add_device () 
{
   devs=`get_devices $1`
   if [ -s $BD ]; then
      cat /tmp/devs | awk "BEGIN { fnd=0 }  
                          { 
                            if ( index(\$0, \"$devs\") ) { fnd=1; print \$0 } 
                            else if ( index(\"$devs\", \$0) ) { fnd=1; print \"$devs\" } 
                            else { print \$0 } 
                          } 
                          END { exit fnd }" > /tmp/$$.tmp
      if (( $? )); then
         mv /tmp/$$.tmp $BD
         exit
      else
         rm /tmp/$$.tmp
         echo $devs >> $BD
      fi
   else
      echo $devs > $BD
   fi
}
function remove_device () 
{
   grep "$1" $BD && sed -i "/$1/ d" $BD || exit
}

name=`get_device_name $DEVICE`
[ $? != 0 ] && exit # если девайс не соответствует отслеживаемым нами то сразу выходим 
if [ -n "$name" ]; then
   case "$ACTION" in
      add)
      add_device "$DEVICE"
      say "$name" "was found"
      ;;
      remove)
      remove_device "$DEVICE"
      say "device" "has been removed"
      ;;
      change)
      say "$name" "was changed"
      ;;
   esac
fi

В $BD ведется база подключенных девайсов. Также, возможно, не стоит отправлять в $BD самую длинную цепочку девайсов, а вместо это оставлять первую прилетевшую.

kim-roader ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.