Используя присвоения make-файла из сценария оболочки

Вы не говорите, как Вы хотите определить то, что отображено, но -o шоу только подобранное выражение, таким образом, grep -o 3071 file просто отобразил бы 3071.

1
07.08.2013, 10:20
3 ответа

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

getmakevar() {
    makefile="$1"
    var="$2"

    make getmakevar -f -  <<EOI
include $makefile

getmakevar:
    @echo \$($var)
EOI
}

Это - совместимый POSIX, и обработает любого и все возможные форматы make-файла (как долго, как это - допустимая гну, делают),


# cat Makefile
bar=baz
myvar = /foo/$(bar)

# getmakevar Makefile myvar
/foo/baz
3
27.01.2020, 23:15

Я сделал чистый POSIX sh версией. Вещи мне нравится приблизительно он:

  • Полностью базирующаяся оболочка (никакие вызовы к внешним командам, кроме printf)
  • Это является общим (функции оболочки являются допускающими повторное использование),
  • Это импортирует определения в текущую среду.

Вещи мне не нравится:

  • Оценка использования. Я старался избегать его, но необходимо сделать определения без жесткого кодирования ими. Я проверяю это, имя разумно и заключает значение в кавычки. Это должно сделать это безопасным, но я не на 100% уверен, что это.
  • POSIX sh ужасен.
  • Нет никаких локальных переменных к функциям в POSIX sh.

Ну, здесь это:

#!/bin/sh

trim_left() {
    _str=$1 _chrs=$2
    while [ "$_chrs" ]; do
        _chr=${_chrs%"${_chrs#?}"}
        while [ "${_str%"${_str#?}"}" = "$_chr" ]; do
            _str=${_str#?}
        done
        _chrs=${_chrs#?}
    done
    printf %s "$_str"
}

trim_right() {
    _str=$1 _chrs=$2
    while [ "$_chrs" ]; do
        _chr=${_chrs%"${_chrs#?}"}
        while [ "${_str#"${_str%?}"}" = "$_chr" ]; do
            _str=${_str%?}
        done
        _chrs=${_chrs#?}
    done
    printf %s "$_str"
}

trim_comment() {
    _str=$1 _marker=$2
    printf %s "${_str%%"$_marker"*}"
}

quote_str() {
    _str=$1 _qstr=
    while [ "$_str" ]; do
        _chr=${_str%"${_str#?}"}
        if [ "$_chr" = "'" ]; then
            _qstr=$_qstr"'\\''"
        else
            _qstr=$_qstr$_chr
        fi
        _str=${_str#?}
    done
    printf "'%s'" "$_qstr"
}

# [a-zA-Z_][a-zA-Z_0-9]
valid_vname() {
    _vname=$1
    case $_vname in
        [[:lower:][:upper:]_]*)
        ;;
        *)
            return 1
        ;;
    esac
    _vname=${_vname#?}

    while [ "$_vname" ]; do
        case $_vname in
            [[:lower:][:upper:]_[:digit:]]*)
            ;;
            *)
                return 1
            ;;
        esac
        _vname=${_vname#?}
    done

    return 0
}

ws='    
'


input_file=$1
[ "$input_file" ] || {
    printf '%s\n' 'usage: script <file>' >&2;
    exit 1
}

while IFS== read -r _name _value; do
    name=$(trim_left "$(trim_right "$_name" "$ws")" "$ws")
    case $_value in
        *'#'*)
            value=$(trim_comment "$_value" '#')
        ;;
        *'//'*)
            value=$(trim_comment "$_value" '//')
        ;;
    esac
    value=$(trim_left "$(trim_right "$value" "$ws")" "$ws")

    if valid_vname "$name"; then
        eval "$name=$(quote_str "$value")";
    fi
done < "$input_file";

echo "$srcdir"
echo "$prefix"
2
27.01.2020, 23:15
#!/bin/sh
FILENAME="<path>"
while read LINE
do
    echo "$LINE"
    if echo "$LINE" | grep -E -q "^srcdir*"
    then
        LINE=$(echo $LINE | cut -d"#" -f1) # No Comment, strip part after #
        LINE=$(echo $LINE | awk -F" // " '{print $1;}') # No Comment, strip part after //
        LINE=$(echo $LINE | tr -d ' ')
        srcdir=$(echo $LINE | tr -d '^srcdir=')
        break
    fi
done < "$FILENAME"

echo $srcdir
1
27.01.2020, 23:15
  • 1
    Все эти последовательные вызовы к grep, cut, awk, tr более сложны, чем это должно быть. Вы пропускаете двойные кавычки вокруг многих подстановок переменных. –  Gilles 'SO- stop being evil' 03.08.2013, 02:35
  • 2
    Кроме того, Вы уверенный, что переменную, которую Вы ищете, будут всегда называть srcdir? Поскольку это кажется слишком трудно кодированным для меня. –  Joseph R. 03.08.2013, 22:59
  • 3
    Давайте попробуем это srcdi = me :) –  a CVn 03.08.2013, 23:06

Теги

Похожие вопросы