Замена процесса на «источник» не работает в Mac OS - PullRequest
0 голосов
/ 09 мая 2019

Фон

У меня есть проект, в котором версия проекта определена как макрос в заголовочном файле C. Я нашел способ извлечь эти данные из заголовочного файла C и обработать их в каком-то скрипте bash в Mac OS.

Проблема

По какой-то причине «Подстановка процессов» не работает, когда я передаю эти данные команде source.

Вот тестовый скрипт bash:

#!/bin/bash

VERSION_BUILD_FILE=$(dirname $0)/Somepath/Version.h

function parseNow() {
    gcc -E -dM "$VERSION_BUILD_FILE" | sed -E '{
        /^#define (VERSION_M|BUILD_NUMBER)/!d
        /#define[ \t]*[^ \t]*$/d
        s/[^ \t]*[ \t]*([^ \t]*)[ \t]*(.*)/\1=\2/
        /(""|\([^\)]*\))/d
    }'
}

function checkVersioVer() {
    echo "$VERSION_MAJOR.$VERSION_MINOR.$BUILD_NUMBER   milestone: $VERSION_MILESTONE"
}

checkVersioVer

echo parseNow result:
parseNow

echo "----"
echo "source parseNow"
source <(parseNow)
checkVersioVer

echo "----"
echo "copy parseNow then source tmp.txt"
cp <(parseNow) tmp.txt
source tmp.txt
rm tmp.txt
checkVersioVer

Это дает такой вывод:

..   milestone: 
parseNow result:
BUILD_NUMBER=1047
VERSION_MAJOR=1
VERSION_MILESTONE="v1.3"
VERSION_MINOR=3
----
source parseNow
..   milestone: 
----
copy parseNow then source tmp.txt
1.3.1047   milestone: v1.3

Как видите, source parseNow часть не работает, но copy parseNow работает, даже если копирование выполняется с подстановкой процесса во временный файл.

Вот пример заголовка:

#define BUILD_NUMBER 1047
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_MILESTONE "v1.3"
// other stuff

Вопрос * * 1023 Почему source <(parseNow) не работает (в Mac OS Mojave)? Можно как нибудь исправить?
Я хотел бы не использовать временный файл для обработки этого файла заголовка C. Это последнее средство. echo $BASH_VERSION отпечатков 3.2.57(1)-release На основе комментариев другие aproches, которые не работают: parseNow | source /dev/fd/0 source /dev/fd/0 < <(parseNow) parseNow | source - # line 26: -: No such file or directory source - < <(parseNow)

1 Ответ

3 голосов
/ 09 мая 2019

Как объяснено в этот ответ , source не работает с подстановкой процессов в более старых версиях bash.

Однако, так как обходной путь, представленный в том же ответе, кажется, не работает для вас, позвольте мне предложить альтернативу:

eval "$(parseNow)"

Я знаю, я знаю, eval плохо и все такое, но на самом деле нет никакой разницы между source /dev/stdin <<< "string" и eval "string".

Лично я думаю, что булл eval, но не все другие небезопасные конструкции, является двойным стандартом. По этому вопросу есть очень интересное сообщение от автора shellcheck:
eval белого воротничка: [[ $var -eq 42 ]] тоже выполняет произвольный код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...