Intereting Posts
Сделать Apache доступ к скрытым файлам (Solaris) Автоматическое монтирование cd или dvd на сервере Ubuntu на основе CLI удалять файлы с определенным шаблоном в своих именах Какая правильная версия dm-cache Как связать (двойное) нажатие клавиши Shift в tmux? Что это за шрифт? FreeNAS: моментальные снимки на реплицированных наборах данных исчезают Разделение большого файла по столбцу со значениями в заголовке в виде имен файлов Файловая система Suse работает только для чтения Защищенные паролем zip-архивы открываются без пароля Расширения файлов и связь с программами в Linux Как запускать локальные (не shell-скрипты) сценарии на удаленном хосте через SSH? Raspbian Jessie Lite «Сброс фабрики» KDE / LightDM – отключить несколько пользователей, которые вошли в систему / 'переключатель пользователя' Можно ли настроить конфигурацию git через несколько репозиториев?

Как вызвать функции Matlab в bash, когда пользовательский ввод является операндом

Я хочу запустить matlab, используя bash, для которого требуется matlab -nodesktop -nosplash -r "functionmat(var1,var2)" . Например, я могу запустить matlab -nodesktop -nosplash -r "functionmat(5,4)" и если это допустимый ввод, он работает и создает некоторые файлы и делает все, что имеет в нем mfile .

Но я хочу, чтобы переменные представляли собой данные, задаваемые пользователем, поэтому он варьируется в каждом прогоне без необходимости изменения скрипта. При запросе пользователь вводит разные входы.

Это не работает (ничего не происходит):

 #!/bin/bash echo "Please variables 1 and 2:" read var1 var2 matlab -nodesktop -nosplash -r "functionmat($var1,$var2)" 

Вызов matlab как это, тоже не работает (говорит, что это ошибка, поскольку, вероятно, он считывает входы типа string, когда предполагается, что это номера):

 matlab -nodesktop -nosplash -r "functionmat('$var1','$var2')" 

Это тоже не работает (ничего не происходит – файлы не созданы):

 sect1="\"" sect2="functionmat(" sect3="," sect4=")" sect5="\"" matlab -nodesktop -nosplash -r "$sect1$sect2$var1$sect3$var2$sect4$sect5" 

Кто-нибудь не знает, как заставить его работать?

Ваше первое предложение должно работать правильно. Я полагаю, что единственный вариант – проверить правильность ввода переменных (пробел разделен, а не разделен запятыми). Вы можете продемонстрировать, что код правильный, слегка изменив его, чтобы напечатать значения двух переменных и напечатать команду matlab а не выполнить ее:

 #!/bin/bash echo "Please variables 1 and 2:" read var1 var2 echo "var1=$var1, var2=$var2." echo matlab -nodesktop -nosplash -r "functionmat($var1,$var2)" 

Ваш первый подход почти прав, и все, что вам нужно, это убедиться, что переменные являются действительно законным синтаксисом Matlab. Второй неверен, потому что в Matlab ввод выглядит как func('1','5') – строки в качестве аргументов. Третий ничего не делает, потому что строка "func(1,5)" является просто строковым литералом. Замените matlab на printf '%s\n' чтобы узнать, что вы переходите в него.

Проверка ввода

Использование declare -i var1 var2 заставляет переменные распознаваться как целые числа , а в присваивании bash присваивает результат оценки string-to-assign как выражения C-стиля (и жалуется на ошибки синтаксиса выражения). Таким образом:

  • Позволяет использовать выражения типа 3*2 (eval'ed to 6 by shell)
  • Не позволяет использовать десятичные числа, например 2.45 .
  • Обеспечивает, что пройденное число является целым числом.
    • Структура, которая выглядит как [[:alpha:]_][[:word:]]* будет распознана как varname, которая получает дополнительную оценку и по умолчанию равна 0, если она не определена.

Когда ошибка вызывается read , вся переменная все еще не инициализирована. Вы можете поймать его так:

 declare -i var1 var2 until ((${#var1[@]} && ${#var2[@]})); do read -p "INPUT! NOW!" var1 var2; done 

Пользовательские расширенные шаблоны глобусов могут использоваться, если вы хотите иметь дело с десятичными знаками (и исключить часть обработки переменных). Обратите внимание, что я слишком ленив, чтобы рассмотреть выражения:

 shopt -s extglob # bash 3, regex =~ is bash 4. until [[ $var1 == +([0-9])?(.*([0-9])) && $var2 == +([0-9])?(.*([0-9])) ]]; do read -p "Please input.. " var1 var2 done 

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

read разделитель

Просто добавьте IFS+=, или что-нибудь еще, что вы хотите, чтобы он был допустимым разделителем перед read .


Этот ответ дополняет и, возможно, комбинацию этих двух ответов выше. Первоначально он редактировался 113859 и 113860 . Для получения дополнительной информации прочитайте главы руководства GNU Bash 3.5.3 (инициализированная проверка), 3.5.7 (IFS), 3.5.8.1 (шаблон) и 4.2 (builtin: declare).

У меня нет Matlab на моем компьютере, поэтому я использовал GNU Octave для проверки правильности моих синтаксических проверок. Существуют также онлайн-сервисы Octave для тех, кто хочет попробовать синтаксис.

Переменные Bash обрабатываются как символьные строки, если не набираются. Я бы начал с попытки объявить тип для ваших переменных. Что-то вроде этого,

 declare -i var1 

Я не оптимист, что объявление этого типа будет для вас решением, но это стоит того.

Если это не работает, почему бы не изменить параметры вашей функции на символьную строку вместо числовых значений? Пусть ваш mfile обрабатывает преобразование в числовой тип по вашему выбору.

Рекомендации:

  • 4,3. Переменные Bash Untyped
  • 9.2. Ввод переменных: объявление или набор

Хорошо, я нашел способ запустить программу

  #!/bin/bash echo "Please enter variables 1 and 2:" read var1 var2 declare -i var1 declare -i var2 mystring="matlab -nodesktop -nosplash -r \"functionmat($var1,$var2);exit\"" eval $mystring 

Спасибо за вашу помощь, если вы ответили