LINUX.ORG.RU

по серьёзному: нужно писать интерпретатор bash на bash

по быдлокодерскому: eval нельзя заюзать?

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

пробовал с эвалом. не получилось

teod0r ★★★★★
() автор топика

Взять python и сделать нужное, например, несколькими наборами токенайзеров.

EXL ★★★★★
()
i=1 ; for j in ' 11 1 1 ' "2 2 22" 3\ 3\ 3 ; do area[$i]=$j ; i=$((i+1)) ; done ; echo ${area[1]} ; echo ${area[2]} ; echo ${area[3]}
sin_a ★★★★★
()
Ответ на: комментарий от spijet

понятно, что так можно.
но строка то читается из файла

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

о чудо! работает.
благодарю. жаль только что лишний раз bash вызывать.
может ещё набегут эксперты и посоветуют более красивый вариант. пока не буду помечать как решённую.

teod0r ★★★★★
() автор топика
Ответ на: комментарий от PexuOne
--- t.bash      2019-05-28 10:19:20.209326099 +0300
+++ t2.bash     2019-05-28 10:19:13.969326355 +0300
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 a="'   1 2 3' \"4 5 6\" 7\ 8\ 9"
-b=`bash -c "for i in $a;"' do echo $i ; done'`
+b=`bash -c "for i in $a;"' do echo "$i" ; done'`
 # echo "\$b == $b"
 
 for i in "$b"
PexuOne
()

На мой взгляд это тот случай, когда лучше использовать python.

shlex – Lexical analysis of shell-style syntaxes.

Note: Три одинарные кавычки - начало/окончание строки.

import shlex

print(list(shlex.shlex( ''' ' 11 1 1 ' "2 2 22" 3\ 3\ 3 ''', posix=True)))


[' 11 1 1 ', '2 2 22', '3 3 3']

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

Я вот что думаю, если ТС для своей задачи «сверху» тоже возьмёт нормальный язык программирования, а не Bash, возможно ему даже этот лексер не понадобится, т. к. будет всё сразу по-людски и сабжевый вопрос просто не возникнет.

EXL ★★★★★
()

Почему с eval не получилось?

$ var="' 11 1 1 ' \"2 2 22\" 3\ 3\ 3"
$ eval set $var
$ echo "$1"
 11 1 1 
$ echo "$2"
2 2 22
$ echo "$3"
3 3 3
$ for val; do echo "$val"; done
 11 1 1 
2 2 22
3 3 3

unterwulf
()
Последнее исправление: unterwulf (всего исправлений: 1)
Ответ на: комментарий от Deleted

чём суть такой расстановки кавычек

в том, что параметры в bash разделяются пробелами.

чтобы это оставался один и тот же параметр, просто не оставляешь пробел между «и'

ну и, в двойных кавычках - $i подставляется, а в одинарных - нет

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

Чего боишься, клоун? Поставь set -x, вместо rm другую команду и посмотри, как отработает предлложенный выше скрипт.

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

Какие, к чёрту, понятия?

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

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

они распространяют дярявый говнокод

Какой к чорту «код»? И вообще, кто тот «отмороженный», который придумал называть команды bash «кодом»?

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

Это вообще к чему?

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

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

Там по ссылке какой-то невнятный тупак.

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

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

Учитывая, что ТС сам упомянул eval, логично предположить, что он в курсе рисков данного метода.

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

Да, давно уже пора сделать standalone парсер шелловской грамматики в части кавычек и экранирования и использовать его из скриптов как внешнюю утилиту. Но я такого ещё не встречал, а написать пока ленюсь.

Дело вкуса, но тащить из-за этого Питон, мне кажется некрасивым.

unterwulf
()
dron@gnu:~$ cat line.txt
' 11 1 1 ' "2 2 22" 3\ 3\ 3
dron@gnu:~$ gcc line.c
dron@gnu:~$ ./a.out 
 11 1 1  2 2 22 3 3 3
dron@gnu:~$ 
#include <stdio.h>
#include <assert.h>

int main(int argc, char *argv[])
{
    FILE * fline = fopen("./line.txt","r");
    assert(fline);
    char line[512] = {0};
    char * res = fgets(line,511,fline);
    fclose(fline);
    assert(res);
    char arr[512] = {0};
    for (int i = 0,x = 0; line[i]!='\n'; i++)
    {
        if(line[i]=='\'' || line[i]=='"' || line[i]=='\\')
        {
            continue;
        }else{
            arr[x++]=line[i];
        };
    };
    printf("%s\n",arr);
    return 0;
}
LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от unterwulf

Если посмотреть темы ТС, видно, что он любитель странного и не особо разбирается в баше, хотя использует его уже весьма долго.

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

благодарю!
про set то я и не подумал

teod0r ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Решение проблемы ::)

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

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

Ему и дано тупо удалить символы, а если у него там миллионы строк в строгом формате (да надо внести изменения) то однострочники будут тратить драгоценное время. Я предложил, выбирать как быть дело ТС

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Ему и дано тупо удалить символы, а если у него там миллионы строк в строгом формате (да надо внести изменения) то однострочники будут тратить драгоценное время. Я предложил, выбирать как быть дело ТС

TC просил разбить строку на элементы массива. В его примере - три элемента массива.

И он ничего не говорил про миллионы строк и какую-то драгоценность времени. Не додумывай требований.

Kroz ★★★★★
()

Встроенная парсилка кавычек есть в xargs

$ xargs printf '[%s]\0' <<EOF
' 11 1 1 ' "2 2 22" 3\ 3\ 3
EOF
[ 11 1 1 ][2 2 22][3 3 3]

выкинь поскорее это опасное убожество с eval и посмотри на этот ответ на стековерфло: https://stackoverflow.com/questions/26067249/reading-quoted-escaped-arguments-correctly-from-a-string/31485948#31485948

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

выкинь поскорее это опасное убожество с eval

Тю, а сам то кавычки у EOF забыл поставить.

$ xargs printf '[%s]\0' <<EOF
' 11 1 1 ' "2 2 22" 3\ 3\ 3 $(echo excute rm)
EOF

vodz ★★★★★
()
Ответ на: комментарий от legolegs

если предварительно в строке заэкранировать опасные символы, eval не будет опасным.

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

Да, косяк. Но у ТС вообще из файла данные, а here doc я чисто для примера притащил.

legolegs ★★★★★
()
Ответ на: комментарий от teod0r

Как-то глупо очищать данные перед подачей в сложный и опасный парсер, когда есть простой и безопасный парсер. Чем проще система, тем она надёжнее и легче поддерживается.

Ещё проще бы было хранить данные с разделителем, через табуляцию например.

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

чем проще система, тем она надёжнее и легче поддерживается.

И тем больше раздражает своей тупостью по возможностям. Ибо сегодня простое будет достаточно, а завтра и $VAR захочется, а то и ${VAR[idx]}, но чтобы $(var) не делало, но была разница у $VAR и «$VAR» и так далее.

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