Как сценарий удара может знать каталог, он установлен в том, когда он получен с. оператор?

как я могу передать функции C имена переменных?

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

Здесь я создал JSON-подобный объект, используя оператор STRING и оператор REPLACE для передачи пары имя / значение. Я выбрал этот метод, потому что есть много библиотек с открытым исходным кодом, которые можно вызывать из C для декодирования JSON объектов. Он также очень гибок в отношении длины текста и количества передаваемых переменных.

[Под ред. Изменен код для размещения всех элементов данных оператора STRING в операторе REPLACE. Изменены некоторые имена, чтобы отразить пары «имя / значение». Удален код длины строки во вложенной программе.]

   program-id. call-c.
   data division.
   working-storage section.
   1 msg.
    2 varA pic x(32) value "Message 1".
    2 varB pic x(32) value "Message 2".
   1 lengths binary.
    2 len-1 pic 9(4).
    2 len-2 pic 9(4).
   replace
       ==name-1== by =="varA"==
           ==value-1== by ==varA(1:len-1)==
       ==name-2== by =="varB"==
           ==value-2== by ==varB(1:len-2)==
       ==newline== by ==x"0a"==
       .
   1 json-string pic x(256).
   procedure division.
   begin.
       compute len-1 = function length (varA)
       call "rtrim-len" using varA len-1

       compute len-2 = function length (varB)
       call "rtrim-len" using varB len-2

       string
           "{" newline
               quote name-1 quote ": "
                 quote value-1 quote "," newline
               quote name-2 quote ": "
                 quote value-2 quote newline
           "}" x"00"
           delimited size into json-string
       call "c_prog" using
           by reference json-string
       stop run
       .

   program-id. rtrim-len.
   data division.
   linkage section.
   1 str pic x(256).
   1 str-len binary pic 9(4).
   procedure division using str str-len.
   begin.
       perform varying str-len from str-len by -1
       until str-len < 1 or str (str-len:1) not = space
           continue
       end-perform
       exit program
       .
   end program rtrim-len.
   end program call-c.

Программа на языке COBOL, заменяющая вызываемую программу C.

   program-id. "c_prog".
   data division.
   working-storage section.
   1 json-string-count binary pic 9(4).
   1 json-string-pos binary pic 9(4).
   1 json-text-count binary pic 9(4).
   1 json-text pic x(64).
   linkage section.
   1 json-string pic x(256).
   procedure division using json-string.
   begin.
       move 0 to json-string-count
       inspect json-string tallying
           json-string-count for characters before x"00"
       move 1 to json-string-pos
       perform until json-string-pos > json-string-count
           unstring json-string delimited x"0a" or x"00"
               into json-text count json-text-count
               pointer json-string-pos
           display json-text (1:json-text-count)
       end-perform
       exit program
       .
   end program "c_prog".

Вывод:

{
"varA": "Message 1",
"varB": "Message 2"
}

Если доступна функция TRIM, вычисления длины, элементы данных и вложенная программа не нужны, и оператор REPLACE становится

   replace
       ==name-1== by =="varA"==
           ==value-1== by ==trim(varA)==
       ==name-2== by =="varB"==
           ==value-2== by ==trim(varB)==
       ==newline== by ==x"0a"==
       .
12
задан Chris Upchurch 8 April 2009 в 19:18
поделиться

4 ответа

Я верю $(dirname "$BASH_SOURCE") сделает то, что Вы хотите, пока файл, который Вы получаете, не является символьной ссылкой.

Если файл, который Вы получаете, может быть символьной ссылкой, можно сделать что-то как следующее для получения истинного каталога:

PRG="$BASH_SOURCE"
progname=`basename "$BASH_SOURCE"`

while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done

dir=$(dirname "$PRG")
19
ответ дан 2 December 2019 в 05:28
поделиться

Другое взятие на проблеме - если Вы используете "." для установки переменных среды, другой стандартный способ сделать, это должно иметь переменные команды установки эха сценария, например:

# settings.sh
echo export CLASSPATH=${CLASSPATH}:/foo/bar

затем оценка вывод:

eval $(/path/to/settings.sh)

Это - то, как работают пакеты как модули. Этот путь также помогает поддерживать оболочки, полученные из sh (X=...; export X) и csh (setenv X ...)

2
ответ дан 2 December 2019 в 05:28
поделиться

Я пытался смешать с вариантами $ (dirname 0$), но он перестал работать, когда .settings файл включен с ".". Если бы я выполнял .settings файл вместо включения его, то это решение работало бы. Вместо этого $ (dirname 0$) всегда возвращается ".", означая текущий каталог. Это перестало работать при выполнении чего-то вроде этого:

CD $ / $./some/path/.settings

0
ответ дан 2 December 2019 в 05:28
поделиться

Этот вид работ. Это работает в том смысле, что можно использовать $ (dirname 0$) синтаксис в .settings файле для определения его дома, так как Вы выполняете этот сценарий в новой оболочке. Однако это добавляет дополнительный слой свертки, где необходимо изменить строки, такие как:

export MYDATE=$(date)

кому:

echo "export MYDATE=\$(date)"

Возможно, это - единственный путь?

0
ответ дан 2 December 2019 в 05:28
поделиться
Другие вопросы по тегам:

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