কোনও অ্যাপ্লিকেশনকে তার স্টাডাউটকে কীভাবে ভাবা যায় এটি একটি টার্মিনাল, পাইপ নয়


147

আমি " স্টিডিন যদি টার্মিনাল বা পাইপ হয় তা সনাক্ত করুন? " এর বিপরীতে করার চেষ্টা করছি ।

আমি একটি অ্যাপ্লিকেশন চালাচ্ছি যা এর আউটপুট ফর্ম্যাটটি পরিবর্তন করছে কারণ এটি STDOUT এ একটি পাইপ সনাক্ত করে এবং আমি এটি ভাবতে চাই যে এটি একটি ইন্টারেক্টিভ টার্মিনাল যাতে পুনর্নির্দেশের সময় আমি একই আউটপুট পাই।

আমি ভাবছিলাম যে এটি কোনও expectস্ক্রিপ্টে মোড়ানো বা proc_open()পিএইচপি ব্যবহার করে এটি করবে, তবে তা হয় না।

সেখানে কোন ধারণা আছে?


8
কি empty.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এমনকি ব্যাসিবক্সে পাওয়া যায় !
ডলম্যান

9
যদি আপনি এটিকে ইন্টারেক্টিভ কিছুতে পাইপ করতে চান, যেমন less -R, যেখানে টার্মিনাল ইনপুট যায় less -R, তবে আপনার কিছু বাড়তি কৌশল প্রয়োজন। উদাহরণস্বরূপ, আমি একটি রঙিন সংস্করণ চেয়েছিলাম git status | less। আপনি পাস প্রয়োজন -Rঅর্ডার এটি রং সম্মান কম, এবং আপনি ব্যবহার করতে হবে scriptপেতে git statusআউটপুট রঙ। তবে আমরা scriptকীবোর্ডটির মালিকানা রাখতে চাই না , আমরা এটিতে যেতে চাই less। তাই আমি এখন এই ব্যবহার এবং এটি ভাল কাজ করে: 0<&- script -qfc "git status" /dev/null | less -R । এই প্রথম কয়েকটি চরিত্র এই কম্যান্ডের জন্য স্টিডিনের কাছাকাছি।
অ্যারন ম্যাকডেইড

2
দ্রষ্টব্য: ইন্টারেক্টিভিটির জন্য উপাদান যাচাইকরণ $-"i" এর জন্য শেল ভেরিয়েবলের দিকে তাকাচ্ছে এমন ক্ষেত্রে এটি কাজ করে না ।
জে টেলর

1
এটা চমৎকার. ওয়াইনের মধ্যে চালিত এক্সিকিউটেবলের মধ্যে এম্বেড থাকা পাইথন লাইব্রেরি সহ অত্যন্ত বিরল ব্যবহারের জন্য আমার এটির দরকার হয়েছিল। আমি যখন টার্মিনালে দৌড়েছিলাম তখন এটি কাজ করেছিল তবে আমি তৈরি করা ডেস্কটপ ফাইলটি চালানোর সময় এটি সর্বদা ক্র্যাশ হয়ে যায় কারণ Py_Initializeসঠিক স্টিডিন / স্টডার দেখেনি।
তাতেশ

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
মনে হচ্ছে না ম্যাকোস-এ কাজ করছে, আমি পেয়েছি script: illegal option -- f
আলেকজান্ডার মিলস

23

Unbuffer স্ক্রিপ্ট যে দিয়ে আসে আশা করা উচিত নয় এই ঠিক হ্যান্ডেল। যদি তা না হয় তবে অ্যাপ্লিকেশনটি এর আউটপুটটির সাথে কী সংযুক্ত রয়েছে তা ছাড়া অন্য কোনও কিছুর দিকে তাকাচ্ছে। TERM এনভায়রনমেন্ট ভেরিয়েবল কী সেট করা আছে।


17

আমি যদি এটা পিএইচপি থেকে করা সম্ভব জানি না, কিন্তু আপনি যদি সত্যিই সন্তানের প্রক্রিয়া প্রয়োজন একটি Tty দেখতে, আপনি একটি তৈরি করতে পারেন টাইম

সি তে:

#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...

তবে, কারণ এটি স্ট্যান্ডআউটে "\ r \ 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
ওএস এক্স সিনট্যাক্সের জন্য ধন্যবাদ, তবে, আপনার পার্লের বক্তব্যটি বিচার করে মনে হচ্ছে আপনি বোঝাতে চেয়েছিলেন যে এটি "\ r \ n" এর উদাহরণগুলি "\ n" এ বদলেছে, অন্যভাবে নয়, সঠিক?
mklement0

8

সুনির্দিষ্ট উত্তরে মন্তব্য করা খুব নতুন, তবে আমি ভেবেছিলাম যে fakettyউপরে ইঙ্গোমেলার-নেট পোস্ট করা ফাংশনটি অনুসরণ করেছি কারণ এটি সম্প্রতি আমাকে সাহায্য করেছে।

আমি দেখতে পেয়েছি যে এটি এমন একটি typescriptফাইল তৈরি করছে যা আমি চাইনি / প্রয়োজন ছিল না তাই আমি স্ক্রিপ্ট লক্ষ্য ফাইল হিসাবে / dev / নাল যুক্ত করেছি:

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

"ইউএনআইএক্স এনভায়রনমেন্ট ইন অ্যাডভান্সড প্রোগ্রামিং, দ্বিতীয় সংস্করণ" বইয়ের স্যাম্পল কোডে একটি পিটিআই প্রোগ্রাম অন্তর্ভুক্ত রয়েছে!

ম্যাক ওএস এক্স-তে pty কীভাবে সংকলন করতে হবে তা এখানে:

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 *

সত্যই অদ্ভুত ত্রুটি: দ্রুত ত্রুটি: অজানা ডোমেন: কোডনিপেটস.জয়েন্ট.কম। দয়া করে পরীক্ষা করুন যে এই ডোমেনটি কোনও পরিষেবায় যুক্ত করা হয়েছে।
i336_
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.