Linux bash if eval

how to evaluate an dynamically generated if elif else statement in shell

im having trouble getting a dynamically generated shell function to evaluate properly (by evaluate i mean «eval» command) this is the desired statement to be evaluated when ran (except the output will be executed/evaluated by eval)

$ package_check_repo_printf if [ $(printf '%s\n' "found $" | grep -i -e ^"$1") ] then url=$POOL0$1 ftp=$ftpPOOL0$1 echo $1 found in $POOL0 elif [ $(printf '%s\n' "found $" | grep -i -e ^"$1") ] then url=$POOL1$1 ftp=$ftpPOOL1$1 echo $1 found in $POOL1 else echo $1 not found fi 
package_check_repo_printf() < for i in $do if [[ $ifgen == "" ]] then printf '%s' "if [ \$(printf '%s\n' \"found \$\" | grep -i -e ^\"\$1\") ] then url=\$POOL0\$1 ftp=\$ftpPOOL0\$1 echo \$1 found in \$POOL0 " ifgen=gen else printf '%s' "elif [ \$(printf '%s\n' \"found \$\" | grep -i -e ^\"\$1\") ] then url=\$POOL$i\$1 ftp=\$ftpPOOL$i\$1 echo \$1 found in \$POOL$i " fi done printf '%s' "else echo \$1 not found fi" > 
package_check_repo_eval() < set -v for i in $do if [[ $ifgen == "" ]] then eval "if [ \$(printf '%s\n' \"found \$\" | grep -i -e ^\"\$1\") ] then url=\$POOL0\$1 ftp=\$ftpPOOL0\$1 echo \$1 found in \$POOL0 " ifgen=gen else eval "elif [ \$(printf '%s\n' \"found \$\" | grep -i -e ^\"\$1\") ] then url=\$POOL$i\$1 ftp=\$ftpPOOL$i\$1 echo \$1 found in \$POOL$i " fi done eval "else echo \$1 not found fi" set +v > 

and its output ( note for this to be CORRECT it should look the same as the package_check_repo_printf’s output as set -v will echo the lines executed as printf is not printing the lines) :

[chakra@chakra-pc UPM]$ unset ifgen [chakra@chakra-pc UPM]$ package_check_repo_eval if [ $(printf '%s\n' "found $" | grep -i -e ^"$1") ] then url=$POOL0$1 ftp=$ftpPOOL0$1 echo $1 found in $POOL0 bash: syntax error: unexpected end of file elif [ $(printf '%s\n' "found $" | grep -i -e ^"$1") ] bash: syntax error near unexpected token `elif' else bash: syntax error near unexpected token `else' [chakra@chakra-pc UPM]$ 

how would i get this to work correctly? note: just to be clear, my goal is to make this function EVAL based instead of PRINTF based a better example would be this (although im not sure if this is acomplishable another way but still, it generates a usable if elif else statement)

dogs=(1 2 3) dog=(pink blue white) colour=(pink black white) dogs_printf() < unset ifgen for i in $do if [[ $ifgen == "" ]] then printf '%s' "for i in \$ do if [[ \$ == \"\$\" ]] then echo dog$i is \"\$\" " ifgen=gen else printf '%s' "elif [[ \$ == \"\$\" ]] then echo dog$i is \"\$\" " fi done printf '%s' "else echo dog \$i not found fi done " > dogs_printf 
[chakra@chakra-pc UPM]$ dogs=(1 2 3) [chakra@chakra-pc UPM]$ dog=(pink blue white) [chakra@chakra-pc UPM]$ colour=(pink black white) [chakra@chakra-pc UPM]$ dogs_printf() < >unset ifgen > for i in $ > do > if [[ $ifgen == "" ]] > then > printf '%s' "for i in \$ > do > if [[ \$ == \"\$\" ]] > then > echo dog$i is \"\$\" > " > ifgen=gen > else > printf '%s' "elif [[ \$ == \"\$\" ]] > then > echo dog$i is \"\$\" > " > fi > done > printf '%s' "else > echo dog \$i not found > fi > done > " > > [chakra@chakra-pc UPM]$ dogs_printf for i in $ do if [[ $ == "$" ]] then echo dog0 is "$" elif [[ $ == "$" ]] then echo dog1 is "$" elif [[ $ == "$" ]] then echo dog2 is "$" else echo dog $i not found fi done [chakra@chakra-pc UPM]$ for i in $ > do > if [[ $ == "$" ]] > then > echo dog0 is "$" > elif [[ $ == "$" ]] > then > echo dog1 is "$" > elif [[ $ == "$" ]] > then > echo dog2 is "$" > else > echo dog $i not found > fi > done dog0 is pink dog 1 not found dog2 is white [chakra@chakra-pc UPM]$ 

Источник

Читайте также:  Linux open 7z archive

Eval как будто условие заявления

Есть ли другой способ использовать переменную как условие для оператора if в bash?

2 ответа

Ваша цитата является проблемой, и вам нужно пространство вокруг == :

VAR='[[ "x" == "y" ]]' if eval $VAR ; then echo "true" else echo "false" fi 

Однако вы должны избегать использования eval настолько далеко, насколько возможно. Вы можете использовать функцию здесь:

if fvar; then echo "true" else echo "false" fi 

Причины, по которым ваш eval состояние оценивается в true потому что у вас есть VAR=»[[ «x»==»y» ]]» где текст внутри [[ а также ]] рассматривается как одна строка. Что так же, как оценка [[ a ]] или же [[ foo ]]

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

Во-первых, ваши x и y должны быть литералами или переменными? Одна из причин, по которой я не уверен, это дополнительные цитаты в задании. Обратите внимание, что они эквивалентны:

$ VAR="[[ "x"=="y" ]]" $ echo $VAR [[ x==y ]] $ VAR="[[ x==y ]]" $ echo $VAR [[ x==y ]] 

Так что в этом случае, говоря

это то же самое, что сказать

Когда у вас возникли проблемы с eval, вы захотите распечатать значение вашей переменной, например, чтобы увидеть, что выполняется.

X ==y — это один аргумент, а оператор [[в единственном строковом аргументе говорит: «это строка ненулевой длины?» Например:

$ if [[ dkfjek ]]; then echo true; else echo false; fi true $ if [[ any_non_zero_length_string ]]; then echo true; else echo false; fi true $ if [[ "" ]]; then echo true; else echo false; fi false 

Чтобы использовать == вам нужны пробелы. Например, без и с eval:

$ if [[ x == x ]]; then echo true; else echo false; fi true $ if [[ x == y ]]; then echo true; else echo false; fi false $ VAR="[[ x == x ]]"; if eval $VAR; then echo true; else echo false; fi true $ VAR="[[ x == y ]]"; if eval $VAR; then echo true; else echo false; fi false 

Обычно, хотя вы действительно хотите избежать eval, если вы не знаете, какое значение может иметь переменная. Рассмотрим фрагмент кода, в котором вы позволяете пользователю решать условие для проверки: вы можете написать что-то вроде этого в скрипте:

read -p "type condition> " COND; VAR="[[ $COND ]]"; if eval $VAR; then echo true; else echo false; fi 

Вы можете запустить его, ожидая ввода / вывода, например:

Читайте также:  Adobe premiere pro аналог linux

Но что, если кто-то вошел в это?

type condition> x == x ]]; touch /tmp/oh-no; [[ true true 

Что такое $VAR? А как насчет /tmp/ о-нет?

$ echo $VAR [[ x == x ]]; touch /tmp/oh-no; [[ true ]] $ ls -l /tmp/oh-no -rw-r--r-- 1 splante isiusers 0 Nov 3 15:17 /tmp/oh-no 

Помните, что синтаксис «если «. «[[» — только одна из возможных команд, но любая составная команда может быть выполнена после if. Теперь предположим, что вместо touch /tmp/oh-no использование вошло в какую-то другую, более разрушительную команду? Это бы тоже исполнилось.

Вы спросили: «Есть ли другой способ использовать переменную в качестве условия для оператора if в bash?» Это типичный способ сравнения двух переменных на эквивалентность строк в bash:

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

Источник

Команда Bash eval

Команда `eval` используется в bash для выполнения аргументов, таких как команда оболочки. Аргументы объединяются в строку и принимаются в качестве входных данных для команды оболочки для ее выполнения. eval выполняет команду в текущей оболочке. Эта команда полезна, когда требуется выполнить любую команду, содержащую специальный оператор или зарезервированные ключевые слова. Эту команду можно использовать в любом сценарии, даже если имя переменной неизвестно до выполнения сценария. Это руководство поможет пользователям Linux научиться пользоваться этой командой.

Синтаксис:

Здесь аргументы анализируются и объединяются в строку, которая будет выполняться оболочкой. eval возвращает код статуса выхода после выполнения команды. `eval` возвращает 0 в качестве кода статуса выхода, если аргумент не указан или предоставлен только нулевой аргумент.

Пример-1: Выполнить команду` wc` с помощью `eval`

Предположим, текстовый файл с именем « Department.txt » содержит следующий текст. Общее количество строк в файле можно подсчитать с помощью команды `wc`.

Department.txt

Следующая команда будет store `wc`, команда для подсчета общего количества строк файла, Department.txt в переменную $ mycommand .

Следующая команда `eval` запустит команду` wc` и напечатает общее количество строк .

Вывод показывает, что файл Department.txt состоит из 6 строк.

Примерl-2: Выполните команду` expr` с помощью `eval`

Создайте файл bash с именем evaltest.sh и добавьте следующий скрипт. Этот скрипт присвоит два целых значения переменной $ x и $ y. Команды `expr` и` echo` назначаются двум переменным, $ c1 и $ c2, которые выполняются позже с помощью команды `eval`.

# Первая командная переменная используется для назначения `expr` команде для сложения значений $ x и $ y
c1 =» `expr $ x + $ y`»

# Вторая командная переменная используется для назначения команды `echo`
c2 =» echo «

#` eval` вычислит и вывести сумму $ x и $ y, выполнив команды переменных $ c1
и $ c2
eval $ c2 $ c1

Сумма 5 и 15 равна 20, которая отображается в выводе.

Читайте также:  Linux virtual machine networking

Пример 3: распечатать значение переменной, присвоенной другой переменной

Создать сценарий bash с именем evaltest2.sh с помощью следующего скрипта. Здесь одна переменная используется для присвоения имени другой переменной, содержащей строковые данные. Команда `eval` напечатает значение переменной, которая содержит имя другой переменной, в качестве содержимого.

evaltest2.sh

# Назначить строковое значение в переменную, $ str1
str1 = «Shell Script»

# Назначьте имя переменной «str1» переменной $ str2
str2 = str1
# Сохраните команду в переменной, $ command
command = «echo»

# Команда `eval` выполнит команду` echo` и вывести значение переменной
, содержащейся в другой переменной
eval $ command $

Будет напечатано значение переменной $ str1.

Есть другой способ получить доступ к значению переменной, имя которой является значением другой переменной. Используя символ «!», Можно получить доступ к значению этого типа переменной. Следующая команда может использоваться как альтернатива предыдущему сценарию, и результат будет таким же.

Пример-4: Создание серии переменных со значениями и вычисление суммы значений с помощью команды `eval`

Создайте сценарий bash с именем evaltest3.sh и добавьте следующий сценарий. Этот скрипт создаст серию переменных и сохранит значения в них с помощью команды eval. Значения переменных будут добавлены и сохранены в переменной с именем $ sum. Затем команда `echo` со строковыми значениями присваивается переменной, которая используется в команде` eval` для вывода значения переменной $ sum.

evaltest3.sh

# Инициализируйте переменную $ sum значением 0
sum = 0

# Объявить цикл for, который будет повторяться 4 раза
для n в
do
# Создать четыре переменные с помощью команды eval
eval x $ n = $ n

# Добавьте значения переменной с помощью $ sum
sum = $ (($ sum + $ x $ n))
done

# Назначить команду `echo` со строкой в ​​переменную
command =» echo ‘Результат суммы =’ »

# Команда `eval` выводит значение суммы с использованием переменных
eval $ command $ sum

Сумма четырех переменных равна 1 + 2 + 3 + 4 = 10, которая выводится .

Пример-5: Использование команды `eval` для удалить список файлов

C создайте файл bash с именем evaltest4.sh со следующим скриптом. Этот сценарий будет читать три аргумента командной строки как имена файлов, которые будут удалены, и сохранит значения аргументов в переменной массива $ fn. Команда rm хранится в переменной $ command. Здесь объявлен цикл For для получения каждого имени файла и удаления файла с помощью команды `eval`, если файл существует.

evaltest4.sh

# Объявить массив
declare -A fn

# Прочитать три аргументы командной строки и сохранить в трех индексах массива
fn [0] = $ 1
fn [1] = $ 2
fn [2] = $ 3

# Сохранение команды удаления в переменной
command = «rm»

# цикл for будет повторяться три раза для чтения трех элементов массива
для индекса в 0 1 2
do
# Проверить, существует или не существует файл
if [[-f $ ]]; затем
# если файл существует, удалите файл
eval $ command $
# Сообщите пользователю, что файл удален
echo «$ удалено.»
Else
# Сообщите пользователю, что файл не существует
echo «$ не существует. «
fi
done

Здесь во время выполнения сценария предоставляются три имени файла. Выходные данные показывают, что в текущем расположении существуют mark.docx и product.docx, файлы удалены, а item.txt не существует в текущем расположении.

Любую команду bash можно выполнить с помощью ` eval`, объявив как строку. Команда eval используется в этом руководстве для выполнения различных встроенных команд bash и создания серии переменных. Использование команды eval будет разрешено для пользователей, и они смогут использовать эту команду для различных целей после прочтения этого руководства.

Источник

Оцените статью
Adblock
detector