किसी एप्लिकेशन को यह सोचने के लिए कैसे चकमा दिया जाए कि उसका स्टडआउट एक टर्मिनल है, न कि पाइप


147

मैं इसके विपरीत " पता लगाने की कोशिश कर रहा हूं कि क्या स्टडिन एक टर्मिनल या पाइप है? "।

मैं एक एप्लिकेशन चला रहा हूं जो इसके आउटपुट स्वरूप को बदल रहा है क्योंकि यह STDOUT पर एक पाइप का पता लगाता है, और मैं चाहता हूं कि यह सोचें कि यह एक इंटरैक्टिव टर्मिनल है ताकि मुझे रीडायरेक्ट करने पर समान आउटपुट प्राप्त हो।

मैं सोच रहा था कि इसे expectस्क्रिप्ट में लपेटना या proc_open()PHP में उपयोग करना यह कर देगा, लेकिन यह नहीं है।

किसी भी विचार वहाँ?


8
क्या खाली .sf.net मदद करता है ?
अपरिपक्व

1
@ कुशल: एक उत्तर होना चाहिए था। रास्ते से महान उपयोग ...
न्यूरो

सवाल स्टडआउट के बारे में बात करता है लेकिन शीर्षक में स्टड का उल्लेख है। मुझे लगता है कि शीर्षक गलत है।
पायोत्र डोब्रोगोस्ट

जवाबों:


177

अहा!

scriptआदेश करता है कि हम क्या चाहते हैं ...

script --return --quiet -c "[executable string]" /dev/null

उसने चाल चली!

Usage:
 script [options] [file]

Make a typescript of a terminal session.

Options:
 -a, --append                  append the output
 -c, --command <command>       run command rather than interactive shell
 -e, --return                  return exit code of the child process
 -f, --flush                   run flush after each write
     --force                   use output file even when it is a link
 -q, --quiet                   be quiet
 -t[<file>], --timing[=<file>] output timing data to stderr or to FILE
 -h, --help                    display this help
 -V, --version                 display version

1
+1: बस एक समस्या के साथ समस्या को रोकें जो स्थैतिक आरंभीकरण करती है। फेडोरा 12 में हाल ही में हुए एक बदलाव ने उस अंतर्द्वंद्व को विफल कर दिया है जब एक्सई लैंक्ड एक टटी में नहीं था। आपकी चाल पूरी तरह से काम करती है। स्क्रिप्ट के डिफ़ॉल्ट रूप से स्थापित होने के कारण मैंने इसे अनबफ़र से अधिक पसंद किया!
न्यूरो

scriptव्यस्त बॉक्स में भी उपलब्ध है !
dolmen

9
यदि आप इसे कुछ इंटरैक्टिव में पाइप करना चाहते हैं, जैसे less -R, जहां टर्मिनल इनपुट जाता है less -R, तो आपको कुछ अतिरिक्त चाल की आवश्यकता है। उदाहरण के लिए, मुझे एक रंगीन संस्करण चाहिए था git status | less। आपको -Rरंगों को सम्मान देने के लिए कम से कम पास करने की आवश्यकता है , और आपको आउटपुट रंग scriptप्राप्त git statusकरने के लिए उपयोग करने की आवश्यकता है । लेकिन हम scriptकीबोर्ड का स्वामित्व नहीं रखना चाहते हैं, हम चाहते हैं कि यह जा सके less। इसलिए मैं अब इसका उपयोग करता हूं और यह अच्छी तरह से काम करता है 0<&- script -qfc "git status" /dev/null | less -R :। उन पहले कुछ पात्रों ने इस एक कमंड के लिए स्टड को बंद कर दिया।
हारून मैकडैड 13

2
नोट: यह उन मामलों में काम नहीं करता है, जहां अन्तरक्रियाशीलता के लिए घटक जाँच $-"i" के लिए शेल चर को देख रहा है ।
जय टेलर

1
ये अद्भुत है। वाइन के भीतर चलने वाले एक निष्पादन योग्य के भीतर एक एम्बेडेड पायथन पुस्तकालय के साथ एक अत्यंत दुर्लभ उपयोग के मामले के लिए मुझे इसकी आवश्यकता थी। जब मैं एक टर्मिनल में दौड़ता था तो यह काम करता था, लेकिन जब मैंने .desktop फ़ाइल को चलाया तो मैंने इसे हमेशा क्रैश किया क्योंकि Py_Initializeउचित स्टड / stderr नहीं देखा।
ततश

60

क्रिस के समाधान के आधार पर , मैं निम्नलिखित छोटे सहायक समारोह के साथ आया:

faketty() {
    script -qfc "$(printf "%q " "$@")" /dev/null
}

संभावित रूप से कमांड के कुछ हिस्सों की सुरक्षा करते हुए printfस्क्रिप्ट की दलीलों का सही ढंग से विस्तार करने के लिए क्वर्की दिखना आवश्यक है $@(नीचे उदाहरण देखें)।

उपयोग:

faketty <command> <args>

उदाहरण:

$ python -c "import sys; print sys.stdout.isatty()"
True
$ python -c "import sys; print sys.stdout.isatty()" | cat
False
$ faketty python -c "import sys; print sys.stdout.isatty()" | cat
True

9
आप शायद --returnविकल्प का उपयोग करना चाहते हैं , यदि आपके संस्करण scriptमें यह है, तो बच्चे की प्रक्रिया के निकास कोड को संरक्षित करने के लिए।
jwd

5
मैं इस फ़ंक्शन को इस तरह से बदलने की सलाह देता हूं: function faketty { script -qfc "$(printf "%q " "$@")" /dev/null; } अन्यथा, एक फ़ाइल typescriptबनाई जाएगी , जो हर बार एक कमांड चलने पर बनाई जाएगी, कई मामलों में।
w0rp

1
MacOS पर काम करने के लिए प्रतीत नहीं होता है, मुझे लगता है script: illegal option -- f
अलेक्जेंडर मिल्स

23

उम्मीद के साथ आने वाली unbuffer स्क्रिप्ट को इस ओके को संभालना चाहिए । यदि नहीं, तो अनुप्रयोग इसके उत्पादन से जुड़ा हुआ है, जैसे कुछ और को देख सकता है, जैसे। TERM पर्यावरण चर किसके लिए निर्धारित है।


17

मुझे नहीं पता कि यह PHP से संभव है, लेकिन अगर आपको वास्तव में TTY देखने के लिए बच्चे की प्रक्रिया की आवश्यकता है, तो आप एक PTY बना सकते हैं ।

सी में:

#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
#include <pty.h>

int main(int argc, char **argv) {
    int master;
    struct winsize win = {
        .ws_col = 80, .ws_row = 24,
        .ws_xpixel = 480, .ws_ypixel = 192,
    };
    pid_t child;

    if (argc < 2) {
        printf("Usage: %s cmd [args...]\n", argv[0]);
        exit(EX_USAGE);
    }

    child = forkpty(&master, NULL, NULL, &win);
    if (child == -1) {
        perror("forkpty failed");
        exit(EX_OSERR);
    }
    if (child == 0) {
        execvp(argv[1], argv + 1);
        perror("exec failed");
        exit(EX_OSERR);
    }

    /* now the child is attached to a real pseudo-TTY instead of a pipe,
     * while the parent can use "master" much like a normal pipe */
}

मैं वास्तव में इस धारणा के तहत था कि expectखुद पीटीवाई बनाता है, हालांकि।


क्या आप जानते हैं कि मैक ओएस एक्स पर बच्चे की प्रक्रिया के रूप में नेटटॉप कैसे चलाया जाता है? मैं अपने ऐप में नेटटॉप का आउटपुट प्राप्त करना चाहता हूं। मैंने कांटेक्ट का उपयोग करने की कोशिश की, लेकिन फिर भी नेटटॉप सफलतापूर्वक नहीं चला सका।
विंस युआन

16

मैक ओएस एक्स पर पिछले उत्तर का उल्लेख करते हुए, "स्क्रिप्ट" का उपयोग नीचे की तरह किया जा सकता है ...

script -q /dev/null commands...

लेकिन, क्योंकि यह स्टडआउट पर "\ n" को "\ n" से बदल सकता है, आपको इस तरह से स्क्रिप्ट की भी आवश्यकता हो सकती है:

script -q /dev/null commands... | perl -pe 's/\r\n/\n/g'

यदि इन कमांड के बीच कुछ पाइप हैं, तो आपको स्टडआउट को फ्लश करने की आवश्यकता है। उदाहरण के लिए:

script -q /dev/null commands... | ruby -ne 'print "....\n";STDOUT.flush' |  perl -pe 's/\r\n/\n/g'

1
OS X सिंटैक्स के लिए धन्यवाद, लेकिन, अपने पर्ल स्टेटमेंट को देखते हुए, ऐसा लगता है कि आपके कहने का मतलब है कि यह "\ r \ n" के उदाहरणों को "\ n" में बदलता है, न कि दूसरे तरीके से, सही?
mklement0

8

विशिष्ट उत्तर पर टिप्पणी करने के लिए बहुत नया है, लेकिन मुझे लगा कि मैं fakettyऊपर दिए गए फ़ंक्शन पर अनुवर्ती कार्रवाई करूंगा, क्योंकि यह हाल ही में मदद की थी।

मैंने पाया कि यह एक ऐसी typescriptफाइल बना रहा था जिसे मैं नहीं चाहता / चाहती थी इसलिए मैंने स्क्रिप्ट लक्ष्य फ़ाइल के रूप में जोड़ा / dev / null:

function faketty { script -qfc "$(printf "%q " "$@")" /dev/null ; }


3

@ ए-रॉन के उत्तर को अपडेट करने के लिए) दोनों लिनक्स और मैकओ पर काम करते हैं बी) अप्रत्यक्ष रूप से स्थिति कोड का प्रचार करते हैं (चूंकि मैको scriptइसका समर्थन नहीं करता है)

faketty () {
  # Create a temporary file for storing the status code
  tmp=$(mktemp)

  # Ensure it worked or fail with status 99
  [ "$tmp" ] || return 99

  # Produce a script that runs the command provided to faketty as
  # arguments and stores the status code in the temporary file
  cmd="$(printf '%q ' "$@")"'; echo $? > '$tmp

  # Run the script through /bin/sh with fake tty
  if [ "$(uname)" = "Darwin" ]; then
    # MacOS
    script -Fq /dev/null /bin/sh -c "$cmd"
  else
    script -qfc "/bin/sh -c $(printf "%q " "$cmd")" /dev/null
  fi

  # Ensure that the status code was written to the temporary file or
  # fail with status 99
  [ -s $tmp ] || return 99

  # Collect the status code from the temporary file
  err=$(cat $tmp)

  # Remove the temporary file
  rm -f $tmp

  # Return the status code
  return $err
}

उदाहरण:

$ faketty false ; echo $?
1

$ faketty echo '$HOME' ; echo $?
$HOME
0

embedded_example () {
  faketty perl -e 'sleep(5); print "Hello  world\n"; exit(3);' > LOGFILE 2>&1 </dev/null &
  pid=$!

  # do something else
  echo 0..
  sleep 2
  echo 2..

  echo wait
  wait $pid
  status=$?
  cat LOGFILE
  echo Exit status: $status
}

$ embedded_example
0..
2..
wait
Hello  world
Exit status: 3

2

मैं दौड़ते समय रंग प्राप्त करने की कोशिश कर रहा था shellcheck <file> | less, इसलिए मैंने उपरोक्त उत्तरों की कोशिश की, लेकिन वे इस विचित्र प्रभाव का उत्पादन करते हैं जहां पाठ क्षैतिज रूप से ऑफसेट होता है जहां से यह होना चाहिए:

In ./all/update.sh line 6:
                          for repo in $(cat repos); do
                                                                  ^-- SC2013: To read lines rather than words, pipe/redirect to a 'while read' loop.

(शेलचेक के साथ अपरिचित लोगों के लिए, चेतावनी के साथ लाइन को समस्या के साथ लाइन अप करना चाहिए।)

शेलचेक के साथ काम करने के लिए ऊपर दिए गए उत्तरों के लिए, मैंने टिप्पणियों में से एक विकल्प की कोशिश की:

faketty() {                       
    0</dev/null script -qfc "$(printf "%q " "$@")" /dev/null
}

यह काम। मैंने --returnइस कमांड को थोड़ा कम अयोग्य बनाने के लिए लंबे विकल्प भी जोड़े और उपयोग किए:

faketty() {                       
    0</dev/null script --quiet --flush --return --command "$(printf "%q " "$@")" /dev/null
}

बाश और ज़श में काम करता है।


1

पुस्तक का नमूना कोड "UNIX पर्यावरण में उन्नत प्रोग्रामिंग, दूसरा संस्करण" में शामिल एक पीटीआई कार्यक्रम भी है!

मैक ओएस एक्स पर पीटी को संकलित करने का तरीका यहां दिया गया है:

man 4 pty  #  pty -- pseudo terminal driver

open http://en.wikipedia.org/wiki/Pseudo_terminal

# Advanced Programming in the UNIX Environment, Second Edition
open http://www.apuebook.com

cd ~/Desktop

curl -L -O http://www.apuebook.com/src.tar.gz

tar -xzf src.tar.gz

cd apue.2e

wkdir="${HOME}/Desktop/apue.2e"

sed -E -i "" "s|^WKDIR=.*|WKDIR=${wkdir}|" ~/Desktop/apue.2e/Make.defines.macos

echo '#undef _POSIX_C_SOURCE' >> ~/Desktop/apue.2e/include/apue.h

str='#include   <sys/select.h>'
printf '%s\n' H 1i "$str" . wq | ed -s calld/loop.c

str='
#undef _POSIX_C_SOURCE
#include <sys/types.h>
'
printf '%s\n' H 1i "$str" . wq | ed -s file/devrdev.c

str='
#include <sys/signal.h>
#include <sys/ioctl.h>
'
printf '%s\n' H 1i "$str" . wq | ed -s termios/winch.c

make

~/Desktop/apue.2e/pty/pty ls -ld *

वास्तव में अजीब त्रुटि, भी: तेजी से त्रुटि: अज्ञात डोमेन: codesnippets.joyent.com। कृपया जांचें कि यह डोमेन एक सेवा में जोड़ा गया है।
०३६__
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.