Может ли кнопка YAD вызывать функцию в скрипте?

Я играю с диалоговыми окнами YAD в BASH, и у меня проблемы с построением кнопки. Я не могу получить кнопку YAD для вызова функции в том же скрипте. Есть ли способ сделать это?

Насколько я понимаю, если я использую следующую конструкцию, нажатие кнопки вызовет команду, следующую за двоеточием. Этот пример (который работает) откроет экземпляр Firefox, если пользователь нажмет кнопку Открыть браузер:

yad --button="Open browser":firefox

У меня есть сценарий с несколькими функциями BASH. Я бы хотел, чтобы нажатие кнопки вызвало одну из функций. Это не так. Ниже приводится простой сценарий, который при запуске демонстрирует неутешительное поведение:

#!/bin/bash,

click_one()
{
   yad --center --text="Clicked the one"
}

click_two()
{
   yad --center --text="Clicked the two"
}

cmd="yad --center --text=\"Click a button to see what happens\" \
      --button=\"One\":click_one \
      --button=\"Two\":2 \
      --button=\"Date\":date \
      --button=\"Exit\":99"

proceed=true

while $proceed; do
    eval "$cmd"
    exval=$?

    case $exval in
        2) click_two;;
        99) proceed=false;;
    esac
done

В приведенном выше коде кнопка Date работает должным образом, вызывая команду date. Кнопки Два и Выход работают, потому что я проверяю значение выхода команды и выполняю переход по его значению. К сожалению (для меня) кнопка Один ничего не делает. Я надеялся, что нажатие на кнопку One вызовет локальную функцию click_one. Я хотел бы знать, есть ли способ отформатировать команду YAD так, чтобы вызывалась функция click_one.

Хотя в приведенном выше коде предлагается обходной путь с использованием значения выхода, моя настоящая цель - применить успешный ответ к кнопке формы, которая, насколько я могу понять, не возвращает значение выхода. Другими словами, следующее также не работает без уведомления, но я бы хотел, чтобы он вызывал функцию click_one:

yad --form --field="One":fbtn click_one

person chuckj    schedule 09.04.2018    source источник


Ответы (2)


Очевидно, нет, это должна быть настоящая команда.

Вы можете: поместить свои функции в отдельный файл и в качестве команды запустить bash, создать этот файл и вызвать функцию.

Здесь я также реструктурирую ваш код, чтобы сохранить команду yad в массиве. Это сделает ваш скрипт более надежным:

# using an array makes the quoting a whole lot easier
cmd=(
    yad --center --text="Click a button to see what happens" 
      --button="One":"bash -c 'source /path/to/functions.sh; click_one'"
      --button="Two":2 
      --button="Date":date 
      --button="Exit":99
)

while true; do
    "${cmd[@]}"      # this is how to invoke the command from the array
    exval=$?
    case $exval in
        2) click_two;;
        99) break;;
    esac
done
person glenn jackman    schedule 09.04.2018
comment
И этот ответ, и ответ от @kyodev включали часть решения с использованием bash -c click_one. Чего не хватает, так это того, что я должен экспортировать функции, чтобы получить к ним доступ из элемента управления yad. В моей последней версии я добавил export -f click_one и export -f click_two перед циклом while, затем unset click_one и unset click_two после (чтобы функции не были доступны после завершения скрипта). +1 за предложение массива команд, конструкция, с которой я ранее не был знаком. - person chuckj; 10.04.2018

возможный способ:

#!/bin/bash


click_one(){
   yad --center --text="Clicked the one"
}

click_two(){
   yad --center --text="Clicked the two"
}

export -f click_one click_two

yad \
    --title "My Title" \
    --center --text="Click a button to see what happens" \
    --button="One":"bash -c click_one" \
    --button="Two":"bash -c click_two" \
    --button="Date":"date" \
    --button="Exit":0


echo $?
person kyodev    schedule 09.04.2018