Оболочка Bourne: как перенаправить на многозначный fd?

В программе на C у меня есть файловый дескриптор (фактический пример: 14, но, конечно, программа не знает этого заранее), открытый для записи. Я хочу вызвать system(3), чтобы что-то запустить и отправить стандартный вывод в этот файловый дескриптор. Конечно, это вызывает /bin/sh, то есть оболочку Bourne, которая не распознает конструкции вида 1>&14. Есть ли альтернативный синтаксис (возможно, с использованием фигурных скобок или чего-то еще), который я могу использовать, чтобы оболочка Bourne увидела 14 и использовала его? Я мог бы, конечно, сделать один из них:

  1. Сделайте комбинацию fork/exec вместо system(3) и перенаправьте вручную.

  2. Перенаправьте вывод в файл, а затем скопируйте данные из него в файловый дескриптор 14.

  3. Поскольку у меня есть root, пусть /bin/sh указывает на Bash.

Самым элегантным способом было бы найти синтаксис, с помощью которого оболочка Bourne будет принимать многозначный номер файлового дескриптора. Есть такой?


person Bill Evans at Mariposa    schedule 10.09.2016    source источник
comment
Я точно знаю, что более новая версия ksh93 поддерживает многозначные файловые дескрипторы. Я почти уверен, что вы ссылаетесь на них как 1>{14} и т. д. Так что вполне вероятно, что zsh и bash также имеют эту функцию. Как вы и просили.. возможно, с помощью брекетов, может быть, вам стоит попробовать? Bourne Shell, определенно не в стандартных версиях, связанных с исходными системами Unix, но кто знает, что вы найдете в более современных версиях, связанных с Linux. (существуют ли настоящие Bourne Shell для Linux?). Удачи.   -  person shellter    schedule 11.09.2016
comment
Для оболочки bourne (которую я использую с FreeBSD; я никогда не сталкивался с ней в Linux) 1>&{14} завершается ошибкой с сообщением об ошибке, а 1>{14} завершается молча. bash использует 1>&14. В то время как в Linux (с которого я мигрирую), я использовал bash в качестве своего /bin/sh. Похоже, на FreeBSD я сделаю то же самое. Это самый простой способ заставить мой унаследованный код работать гладко.   -  person Bill Evans at Mariposa    schedule 11.09.2016
comment
Хорошая вещь. Спасибо за отзыв/информацию. Похоже, вы нашли решение, рад, что вы можете двигаться вперед. Всем удачи!   -  person shellter    schedule 11.09.2016
comment
... за исключением того, что я только что обнаружил, что в bash отсутствует то, что есть в оболочке bourne: команда setvar. Это ломает основные сценарии оболочки, которые запускаются при загрузке FreeBSD. Итак, вернемся к чертежной доске. Возможно, лучшим решением будет создать функцию C с именем bash_system, которая похожа на system(3), за исключением того, что она вызывает bash, а не /bin/sh.   -  person Bill Evans at Mariposa    schedule 11.09.2016


Ответы (1)


Рассмотрим мои любимые правила оптимизации: (1) Не оптимизируйте. (2) Для экспертов: пока не оптимизируйте.

Ситуация, возникающая в вопросе, будет (для меня) возникать в коде, который будет выполняться не более 100 раз в день. Итак, этого будет достаточно:

sprintf(big_string,
        "bash -c \"somethingsomething 1>&%d\"",
        the_fd
       );
person Bill Evans at Mariposa    schedule 12.09.2016