Я хочу передать stdin скрипту bash скрипту python, который называется в этом скрипте bash

9

У меня есть скрипт bash, вызывающий скрипт на python, который я хочу fileпередать через stdin. Вызов сценария bash:

./script.sh < file

И содержание script.sh:

#! /usr/bin/env bash
pushd /some/python/virtual/environment/working/dir
source venv/bin/activate
python main.py ??????
deactivate
popd

Я не знаю, что заполнять, ??????чтобы передать содержимое fileданного сценария bash как stdin в сценарий python main.py.

Обратите внимание , что fileможет быть существенным текстовый файл и использовать в Bash readявляется не желательным.

Использование stdin при вызове скрипта bash является обязательным. Я гибкий, чтобы передать все, что угодно main.py.

Есть какие-нибудь идеи, как решить эту головоломку?

прибавление

Ответ @cas дал мне понять, что мне также нужно объяснить, в каком контексте я пытаюсь использовать script.sh.

Я хочу использовать script.shв качестве сценария пересылки~/.forward , с содержанием:

|/path/to/script.sh

Какой постфикс называется как /path/to/script.sh; журнал ясно об этом. Простой тест с использованием урезанной версии скрипта Python, например:

|/path/to/simple/main.py

Демонстрирует, что postfix выполняет вызов main.pyс содержимым почты на stdin. Но комбинация, похоже, не работает.

nanitous
источник
Вы используете собственный localLDA postfix или что-то еще, например procmailили deliver? есть ли в вас ~/.bashrcчто-то, что может нарушить окружающую среду, как видно из main.pyбега изнутри script.sh? может быть, войти в среду, запустив что-то вроде { typeset -p ; echo } >> "/tmp/forward.log"в script.sh.
Cas

Ответы:

15

Предполагая, что ваш main.pyсценарий правильно написан для чтения из stdin и что ничего не venv/bin/activateчитает из stdin (*), ??????должно быть «вообще ничего».

В bash-скрипте нет предыдущих команд, которые будут использовать stdin до python, поэтому python просто начнет его использовать.

#/bin/bash
pushd /some/python/virtual/environment/working/dir
source venv/bin/activate
python main.py
deactivate

Или сделайте main.pyисполняемый файл и запустите его напрямую как ./main.py... работает так же, в любом случае.

(*) если бы это было так, вы, вероятно, не смогли бы сделать это вообще, без чего-то уродливого, например, захват всего stdin в переменную и затем <<<сначала переадресация или перенаправление переменной в venv/bin/activateпотом main.py.


Для очень очевидного примера того, что здесь происходит и почему это работает, рассмотрим следующий скрипт sh kitten.sh:

#!/bin/sh
cat

Он просто запускается cat, который начинает чтение со стандартного ввода и выводит его ввод в стандартный вывод.

саз
источник
5
Оууу ... котенок такой милый, у него есть своя линия Шебанга.
Cas
HI @cas Спасибо за исчерпывающий ответ. И да, это работает так, как должно. Я расширил свой вопрос, чтобы уточнить, в каком контексте я пытаюсь его использовать, а где - нет. Может быть, тогда этот SE - неправильный форум, чтобы задать вопрос.
nanitous
Редактирование заняло у меня более 6 минут ;-)
няня
Если другие команды в начале сценария требуют использования stdin (будущие изменения в сценарии и т. Д.), Некоторые операционные системы имеют псевдо-имена файлов, которые можно передавать в качестве заполнителей. Например, во многих версиях Linux /dev/stdinесть файл устройства (или символическая ссылка на него), который будет выполнять правильные действия при чтении. Конечно, компромисс заключается в том, что переносимость ограничена операционными системами, чьи специальные имена вы знаете, например, назначением локальной переменной соответствующего поддельного имени файла и последующим использованием этой переменной в качестве аргумента python main.py.
Ти Стрга
вся цель сценария OP состоит в том, чтобы настроить среду для python, а затем передать stdin в main.py, так что все, что это сделало, нарушило бы его.
Cas