টার্মিনাল এবং লগ ফাইলে যাওয়ার জন্য কীভাবে আমি STDOUT এবং STDERR উভয়কে পেতে পারি?


112

আমার কাছে একটি স্ক্রিপ্ট রয়েছে যা অ প্রযুক্তিগত ব্যবহারকারীরা ইন্টারেক্টিভভাবে চালিত হবে। স্ক্রিপ্টটি STDOUT এ স্থিতির আপডেট লিখেছে যাতে ব্যবহারকারী নিশ্চিত হয়ে যায় যে স্ক্রিপ্টটি ঠিক আছে কিনা running

আমি STDOUT এবং STDERR উভয়ই টার্মিনালে পুনঃনির্দেশিত করতে চাই (যাতে ব্যবহারকারী দেখতে পান যে স্ক্রিপ্টটি কাজ করছে এবং দেখতে সমস্যা আছে কিনা)। আমি উভয় স্ট্রিম একটি লগ ফাইলে পুনঃনির্দেশ করতে চাই।

আমি নেট উপর একগুচ্ছ সমাধান দেখেছি। কিছু কাজ করে না এবং অন্যেরা মারাত্মক জটিল। আমি একটি কার্যক্ষম সমাধান বিকাশ করেছি (যা আমি উত্তর হিসাবে প্রবেশ করব), তবে এটি ক্লডজি।

নিখুঁত সমাধানটি কোডের একক লাইন যা কোনও স্ক্রিপ্টের শুরুতে অন্তর্ভুক্ত হতে পারে যা উভয় প্রবাহকে টার্মিনাল এবং লগ ফাইল উভয়কে প্রেরণ করে।

সম্পাদনা: STDERR কে STDOUT এ পুনঃনির্দেশিত করা এবং ফলাফল টি-তে কাজ করার জন্য পাইপিং করা, তবে এটি আউটপুটটিকে পুনঃনির্দেশিত এবং পাইপ করতে স্মরণকারী ব্যবহারকারীদের উপর নির্ভর করে। আমি চাই লগিংটি বোকা-প্রমাণ এবং স্বয়ংক্রিয় হয়ে উঠুক (এ কারণেই আমি সমাধানটি স্ক্রিপ্টে এম্বেড করতে সক্ষম হতে চাই like)


: অনুরূপ প্রশ্ন: অন্যান্য পাঠকদের জন্য stackoverflow.com/questions/692000/...
pevik

4
আমি বিরক্ত হয়েছি যে @ জেসনসাইডস ব্যতীত সবাই (আমাকে সহ!) বিচ্ছিন্ন হয়ে পড়ে এবং একটি আলাদা প্রশ্নের উত্তর দিয়েছিল। এবং জেসনের উত্তরটি বিশ্বাসযোগ্য নয়, যেমনটি আমি মন্তব্য করেছি। আপনি যে প্রশ্নটি করেছেন (এবং আপনার EDIT এ জোর দিয়েছিলেন) তার সত্যিকারের নির্ভরযোগ্য উত্তর দেখতে আমি পছন্দ করব।
ডন হ্যাচ

ওহ অপেক্ষা, আমি এটি আবার নিতে। @ পালট্রম্বলিনের গৃহীত উত্তরগুলি এর উত্তর দেয়। আমি এটি এতদূর পড়িনি।
ডন হ্যাচ

উত্তর:


179

কোনও ফাইল এবং স্ক্রিনে পুনর্নির্দেশ করতে "টি" ব্যবহার করুন। আপনি যে শেলটি ব্যবহার করছেন তার উপর নির্ভর করে আপনাকে প্রথমে স্ট্ডারটি স্টাডাউট ব্যবহার করে পুনর্নির্দেশ করতে হবে

./a.out 2>&1 | tee output

বা

./a.out |& tee output

সিএসএসে, "স্ক্রিপ্ট" নামে একটি অন্তর্নির্মিত কমান্ড রয়েছে যা স্ক্রিনে যাওয়া ফাইলগুলিতে যাবতীয় ক্যাপচার করবে। আপনি এটি "স্ক্রিপ্ট" টাইপ করে শুরু করেন, তারপরে আপনি যা ক্যাপচার করতে চান তা করুন, তারপরে স্ক্রিপ্ট ফাইলটি বন্ধ করতে কন্ট্রোল-ডি চাপুন। আমি sh / bash / ksh এর সমতুল্য জানি না।

এছাড়াও, যেহেতু আপনি ইঙ্গিত করেছেন যে এগুলি আপনার নিজের শ স্ক্রিপ্ট যা আপনি সংশোধন করতে পারেন তাই আপনি পুরো স্ক্রিপ্টটি ব্রেস বা বন্ধনীর সাহায্যে ঘিরে রেখে অভ্যন্তরীণভাবে পুনর্নির্দেশটি করতে পারেন, যেমন

  #!/bin/sh
  {
    ... whatever you had in your script before
  } 2>&1 | tee output.file

4
আমি জানতাম না যে আপনি শেল স্ক্রিপ্টগুলিতে কমান্ডগুলি বন্ধনী করতে পারেন। মজাদার.
জেমি

4
আমি বন্ধনী শর্টকাট প্রশংসা করি! কোনও কারণে, 2>&1 | tee -a filenameস্ট্রিডারটি আমার স্ক্রিপ্ট থেকে ফাইলটিতে সংরক্ষণ করা হয়নি, তবে আমি কমান্ডটি অনুলিপি করে টার্মিনালে আটকালে এটি ঠিকঠাক হয়েছিল! যদিও বন্ধনী ট্রিক কাজ করে।
এড ব্রান্নিন

8
নোট করুন যে স্টাডাউট এবং স্টডারারের মধ্যে পার্থক্যটি নষ্ট হয়ে যাবে, যেমন টি স্টাডাউটের সমস্ত কিছু মুদ্রণ করে।
ফ্লিম

4
এফওয়াইআই: 'স্ক্রিপ্ট' কমান্ড বেশিরভাগ বিতরণে উপলব্ধ (এটি
ইউজার

4
@ ফ্লিম, স্টাডাউট এবং স্টাডারের মধ্যে পার্থক্য বজায় রাখার কোনও উপায় (অন্য কোনও উপায়) আছে কি?
গ্যাব্রিয়েল

20

আধ দশক পরে পৌঁছে ...

আমি বিশ্বাস করি এটি ওপি কর্তৃক চাওয়া "নিখুঁত সমাধান"।

আপনার বাশ স্ক্রিপ্টের শীর্ষে আপনি যুক্ত করতে পারেন এমন একটি লাইনার এখানে:

exec > >(tee -a $HOME/logfile) 2>&1

এখানে একটি ছোট স্ক্রিপ্ট এটির ব্যবহার দেখায়:

#!/usr/bin/env bash

exec > >(tee -a $HOME/logfile) 2>&1

# Test redirection of STDOUT
echo test_stdout

# Test redirection of STDERR
ls test_stderr___this_file_does_not_exist

(দ্রষ্টব্য: এটি কেবল বাশের সাথে কাজ করে It এটি / বিন / শের সাথে কাজ করবে না ))

এখান থেকে অভিযোজিত ; আসলটি আমি যা বলতে পারি তা থেকে লগফাইলে এসটিডিআরআর ধরেনি। এখান থেকে একটি নোট সহ স্থির ।


4
নোট করুন যে স্টাডাউট এবং স্টডারারের মধ্যে পার্থক্যটি নষ্ট হয়ে যাবে, যেমন টি স্টাডাউটের সমস্ত কিছু মুদ্রণ করে।
ফ্লিম

@ ফ্লিম স্ট্ডারকে বিভিন্ন টি প্রক্রিয়াতে পুনঃনির্দেশিত করা যেতে পারে যা আবার স্ট্ডারকে পুনঃনির্দেশিত করা যেতে পারে।
জার্নো

: @Flimm, আমি jarno এর পরামর্শ এখানে লিখেছিলেন stackoverflow.com/a/53051506/1054322
MatrixManAtYrService

4
এই সমাধানটি, এখন পর্যন্ত প্রস্তাবিত অন্যান্য সমাধানগুলির মতো, জাতি-প্রবণ। এটি হ'ল, যখন বর্তমান স্ক্রিপ্টটি সম্পূর্ণ হবে এবং ফিরে আসে, হয় ব্যবহারকারীর প্রম্পট বা কিছু উচ্চ-স্তরের কলিং স্ক্রিপ্টে, টি, যা পটভূমিতে চলছে, এখনও চলতে থাকবে এবং পর্দায় এবং শেষের কয়েকটি লাইন প্রসারণ করতে পারে লগফিলটি দেরিতে (এটি প্রম্পটের পরে পর্দায় এবং লগফাইলে সম্পূর্ণ হওয়ার প্রত্যাশার পরে লগফাইলে)
ডন হ্যাচ

4
তবে, এখন পর্যন্ত প্রস্তাবিত এটিই একমাত্র উত্তর যা আসলে প্রশ্নটিকে সম্বোধন করে!
ডন হ্যাচ

11

নমুনা

the_cmd 1> >(tee stdout.txt ) 2> >(tee stderr.txt >&2 )

এই উভয় stdout- এ এবং দ্বারা stderr আলাদাভাবে পুননির্দেশনা, এবং এটি পাঠায় পৃথক কলারের কাছে stdout- এ এবং দ্বারা stderr কপি (আপনার টার্মিনাল হতে পারে যা)।

  • Zsh এ, teeগুলি শেষ না হওয়া পর্যন্ত এটি পরবর্তী বিবৃতিতে অগ্রসর হবে না ।

  • ব্যাশে, আপনি দেখতে পাবেন যে আউটপুটের চূড়ান্ত কয়েকটি লাইন পরে উপস্থিত হবে পরবর্তী যে বিবৃতি আসার ।

উভয় ক্ষেত্রেই, ডান বিটগুলি সঠিক জায়গায় যায়।


ব্যাখ্যা

এখানে একটি স্ক্রিপ্ট (সঞ্চিত। / নমুনা):

#! /usr/bin/env bash
the_cmd()
{
    echo out;
    1>&2 echo err;
}

the_cmd 1> >(tee stdout.txt ) 2> >(tee stderr.txt >&2 )

এখানে একটি অধিবেশন:

$ foo=$(./example)
    err

$ echo $foo
    out

$ cat stdout.txt
    out

$ cat stderr.txt
    err

এখানে কিভাবে এটা কাজ করে:

  1. উভয় teeপ্রক্রিয়া শুরু হয়েছে, তাদের স্ট্ডিনগুলি ফাইল বর্ণনাকারীদের জন্য নিযুক্ত করা হয়েছে। যেহেতু তারা প্রক্রিয়া বিকল্পগুলিতে আবদ্ধ রয়েছে , সেই ফাইল বর্ণনাকারীদের পাথগুলি কলিং কমান্ডে প্রতিস্থাপন করা হয়েছে, সুতরাং এখন এটি এরকম কিছু দেখাচ্ছে:

the_cmd 1> /proc/self/fd/13 2> /proc/self/fd/14

  1. the_cmd রান, প্রথম ফাইল বর্ণনাকারী stdout লিখতে, এবং দ্বিতীয় এক স্ট্যাডার।

  2. বাশের ক্ষেত্রে, একবার the_cmdশেষ হয়ে গেলে , নীচের বিবৃতিটি অবিলম্বে ঘটে (যদি আপনার টার্মিনাল কলকারী হয়, তবে আপনি আপনার প্রম্পট উপস্থিত দেখবেন)।

  3. Zsh ক্ষেত্রে, একবার the_cmdশেষ হলে, শেলটি teeএগিয়ে যাওয়ার আগে উভয় প্রক্রিয়া শেষ হওয়ার জন্য অপেক্ষা করে। আরো এই এখানে

  4. প্রথম teeপ্রক্রিয়া, যা the_cmdস্টাডাউট থেকে পড়ছে , সেই স্টাডাউটের একটি অনুলিপি কলারের কাছে লিখে দেয় কারণ এটিইtee করে। এর ফলাফলগুলি পুনঃনির্দেশিত হয় না, তাই তারা এটিকে আবার অপরিবর্তিত কলারের কাছে ফিরিয়ে দেয়

  5. দ্বিতীয় teeপ্রক্রিয়াটি stdoutকলারের দিকে পুনঃনির্দেশিত হয়েছে stderr(যা ভাল, কারণ এটি স্টিডিন the_cmdস্টাডার থেকে পড়ছে )। সুতরাং এটি যখন তার stdout লিখতে, সেই বিটগুলি কলারের স্টাডারের কাছে যায়।

এটি স্টার্ডার ফাইল এবং কমান্ডের আউটপুটে উভয়ই স্টডআউট থেকে পৃথক রাখে।

প্রথম টি যদি কোনও ত্রুটি লিখতে থাকে তবে তারা উভয় স্ট্ডার ফাইল এবং কমান্ডের স্টার্ডারে প্রদর্শিত হবে, যদি দ্বিতীয় টি কোনও ত্রুটি লিখে থাকে তবে তারা কেবলমাত্র টার্মিনালের স্ট্যাডারে প্রদর্শিত হবে।


এটি দেখতে সত্যিই দরকারী এবং আমি কী চাই। যদিও আমি উইন্ডোজ ব্যাচ স্ক্রিপ্টে বন্ধনী ব্যবহারের (প্রথম পংক্তিতে দেখানো হয়েছে) প্রতিলিপি তৈরি করতে পারি তা নিশ্চিত না। ( teeপ্রশ্নে সিস্টেমে উপলব্ধ।) আমি যে ত্রুটি পেয়েছি তা হ'ল "প্রক্রিয়াটি ফাইলটি অ্যাক্সেস করতে পারে না কারণ এটি অন্য প্রক্রিয়া দ্বারা ব্যবহৃত হচ্ছে।"
আগি হামারথিফ

এই সমাধানটি, এখন পর্যন্ত প্রস্তাবিত অন্যান্য সমাধানগুলির মতো, জাতি-প্রবণ। এটি হ'ল, যখন বর্তমান স্ক্রিপ্টটি সম্পূর্ণ হবে এবং ফিরে আসে, হয় ব্যবহারকারীর প্রম্পট বা কিছু উচ্চ-স্তরের কলিং স্ক্রিপ্টে, টি, যা পটভূমিতে চলছে, এখনও চলতে থাকবে এবং পর্দায় এবং শেষের কয়েকটি লাইন প্রসারণ করতে পারে লগফিলটি দেরিতে (এটি প্রম্পটের পরে পর্দায় এবং লগফাইলে সম্পূর্ণ হওয়ার প্রত্যাশার পরে লগফাইলে)
ডন হ্যাচ

4
@ ডনহ্যাচ আপনি কি কোনও সমস্যার প্রস্তাব দিতে পারেন যা এই সমস্যাটিকে সংশোধন করে?
পাইপ্লিপ

আমি এমন একটি পরীক্ষার ক্ষেত্রেও আগ্রহী যেটি রেসটি দৃশ্যমান করে। এটি সন্দেহজনক নয়, তবে এটি এড়ানোর চেষ্টা করা শক্ত কারণ আমি এটি ঘটতে দেখিনি।
ম্যাট্রিক্সম্যানএটিআইআরসেবা

@pylipp আমার কাছে সমাধান নেই। আমি একটি খুব আগ্রহী হবে ।
ডন হ্যাচ

4

আপনার স্ট্যান্ডারকে স্ট্যান্ডআউটে পুনর্নির্দেশ করার জন্য আপনার কমান্ডে এটি যুক্ত করুন: 2>&1 টার্মিনালে আউটপুট এবং ফাইলটিতে লগ ইন করার জন্য আপনার ব্যবহার করা উচিতtee

উভয় একসাথে দেখতে হবে:

 mycommand 2>&1 | tee mylogfile.log

সম্পাদনা: আপনার স্ক্রিপ্ট এম্বেড করার জন্য আপনি একই কাজ করতে হবে। সুতরাং আপনার স্ক্রিপ্ট

#!/bin/sh
whatever1
whatever2
...
whatever3

হিসাবে শেষ হবে

#!/bin/sh
( whatever1
whatever2
...
whatever3 ) 2>&1 | tee mylogfile.log

4
নোট করুন যে স্টাডাউট এবং স্টডারারের মধ্যে পার্থক্যটি নষ্ট হয়ে যাবে, যেমন টি স্টাডাউটের সমস্ত কিছু মুদ্রণ করে।
ফ্লিম

4

সম্পাদনা: আমি দেখতে পাচ্ছি যে আমি লাইনচ্যুত হয়েছি এবং জিজ্ঞাসা করা ব্যক্তির থেকে আলাদা প্রশ্নের উত্তর দিয়ে শেষ করেছি। আসল প্রশ্নের উত্তর পল টম্বলিনের উত্তরের নীচে রয়েছে। (আপনি যদি কোনও কারণে স্টাডাউট এবং স্টডারকে আলাদাভাবে পুনর্নির্দেশের জন্য সেই সমাধানটি বাড়িয়ে তুলতে চান তবে আপনি এখানে বর্ণিত কৌশলটি ব্যবহার করতে পারেন))


আমি একটি উত্তর চাই যা স্টাডাউট এবং স্টাডারের মধ্যে পার্থক্য সংরক্ষণ করে। দুর্ভাগ্যক্রমে এখনও অবধি দেওয়া সমস্ত উত্তর যে এই পার্থক্যটি সংরক্ষণ করে রেস-প্রবণ: এগুলি অসম্পূর্ণ ইনপুট দেখে প্রোগ্রাম ঝুঁকিপূর্ণ করে আমি মন্তব্যগুলিতে উল্লেখ করেছি।

আমি মনে করি অবশেষে আমি একটি উত্তর পেয়েছি যা পার্থক্য সংরক্ষণ করে, রেসের ঝুঁকিপূর্ণ নয়, এবং ভয়ঙ্করভাবে বিব্রতও নয়।

প্রথম বিল্ডিং ব্লক: স্টাডাউট এবং স্টডারকে অদলবদল করতে:

my_command 3>&1 1>&2 2>&3-

দ্বিতীয় বিল্ডিং ব্লক: যদি আমরা কেবল স্টার্ডার ফিল্টার করতে চাইতাম (উদাহরণস্বরূপ টি) আমরা স্টাডাউট এবং স্ট্ডার অদলবদল, ফিল্টারিং এবং তারপরে ফিরে অদলবদল করে এটি সম্পাদন করতে পারি:

{ my_command 3>&1 1>&2 2>&3- | stderr_filter;} 3>&1 1>&2 2>&3-

এখন বাকিটি সহজ: আমরা শুরুতে একটি স্টাডাউট ফিল্টার যুক্ত করতে পারি:

{ { my_command | stdout_filter;} 3>&1 1>&2 2>&3- | stderr_filter;} 3>&1 1>&2 2>&3-

বা শেষে:

{ my_command 3>&1 1>&2 2>&3- | stderr_filter;} 3>&1 1>&2 2>&3- | stdout_filter

নিজেকে বোঝাতে যে উপরের দুটি আদেশই কাজ করে, আমি নিম্নলিখিতগুলি ব্যবহার করেছি:

alias my_command='{ echo "to stdout"; echo "to stderr" >&2;}'
alias stdout_filter='{ sleep 1; sed -u "s/^/teed stdout: /" | tee stdout.txt;}'
alias stderr_filter='{ sleep 2; sed -u "s/^/teed stderr: /" | tee stderr.txt;}'

আউটপুট হল:

...(1 second pause)...
teed stdout: to stdout
...(another 1 second pause)...
teed stderr: to stderr

এবং আমার প্রম্পট teed stderr: to stderrপ্রত্যাশার সাথে সাথেই " " এর পরে ফিরে আসবে।

Zsh সম্পর্কে পাদটীকা :

উপরের সমাধানটি ব্যাশে কাজ করে (এবং সম্ভবত কিছু অন্যান্য শাঁস, আমি নিশ্চিত নই), তবে এটি zsh এ কাজ করে না। এটি zsh এ ব্যর্থ হওয়ার দুটি কারণ রয়েছে:

  1. সিনট্যাক্স 2>&3-zsh দ্বারা বোঝা যায় না; যে হিসাবে আবার লিখতে হবে2>&3 3>&-
  2. zsh এ (অন্যান্য শাঁসের বিপরীতে), যদি আপনি ইতিমধ্যে উন্মুক্ত কোনও ফাইল বর্ণনাকারীকে পুনর্নির্দেশ করেন তবে কিছু ক্ষেত্রে (এটি কীভাবে সিদ্ধান্ত নেয় আমি সম্পূর্ণ বুঝতে পারি না) এটি পরিবর্তে একটি অন্তর্নিবিষ্ট টি-জাতীয় আচরণ করে। এটি এড়াতে, আপনাকে প্রতিটি এফডি এটি পুনঃনির্দেশ করার আগে বন্ধ করতে হবে।

সুতরাং, উদাহরণস্বরূপ, আমার দ্বিতীয় সমাধানটি zsh এর জন্য আবার লিখতে হবে {my_command 3>&1 1>&- 1>&2 2>&- 2>&3 3>&- | stderr_filter;} 3>&1 1>&- 1>&2 2>&- 2>&3 3>&- | stdout_filter (যা কাজ করে, তবে ভয়াবহভাবে ভার্বোস হয়)।

অন্যদিকে, আপনি zsh এর আরও কম সংক্ষিপ্ত সমাধান পেতে zsh এর রহস্যময় অন্তর্নিহিত অন্তর্নিহিত টিজিংয়ের সুবিধা নিতে পারেন, যা মোটেও টি চালায় না:

my_command >&1 >stdout.txt 2>&2 2>stderr.txt

(আমি যে দস্তাবেজগুলি দেখেছি তা অনুমান করতাম না যে আমি >&1এবং 2>&2এটিই ছিল যা zsh এর অন্তর্নিহিত টিজকে ট্রিগার করে; আমি এটি পরীক্ষামূলক-ত্রুটি দ্বারা খুঁজে পেয়েছি))


আমি এটিকে ঘিরে বাশে খেলেছি এবং এটি ভাল কাজ করে। সামঞ্জস্যতা (আমার মতো) ধরে নেওয়ার অভ্যাস সহ zsh ব্যবহারকারীদের জন্য কেবল একটি সতর্কতা, এটি সেখানে অন্যরকম আচরণ করে: gist.github.com/MatrixManAtYrService/…
ম্যাট্রিক্সম্যানআটিআরসিয়ারসোর্স

@ ম্যাট্রিক্সম্যান অ্যাটায়ার সার্ভিস আমি বিশ্বাস করি যে zsh পরিস্থিতি সম্পর্কে আমি একটি হ্যান্ডেল পেয়েছি এবং এটি প্রমাণিত হয়েছে যে zsh এর মধ্যে আরও পরিষ্কার সমাধান রয়েছে। আমার সম্পাদনা "zsh সম্পর্কে পাদটীকা" দেখুন।
ডন হ্যাচ

এই জাতীয় বিশদটি সমাধানের জন্য ব্যাখ্যা করার জন্য ধন্যবাদ। আপনি কী জানেন কীভাবে my_functionনেস্টেড স্টাডাউট / স্টার্ডার ফিল্টারিংয়ে কোনও ফাংশন ( ) ব্যবহার করার সময় রিটার্ন কোডটি পুনরুদ্ধার করবেন ? আমি করেছি { { my_function || touch failed;} 3>&1 1>&2 2>&3- | stderr_filter;} 3>&1 1>&2 2>&3- | stdout_filterতবে ব্যর্থতার সূচক হিসাবে একটি ফাইল তৈরি করা অদ্ভুত বোধ করে ...
পাইপ্লিপ

পছন্দ করেছেন আপনি এটি একটি পৃথক প্রশ্ন হিসাবে (সম্ভবত একটি সহজ পাইপলাইন সহ) জিজ্ঞাসা করতে পারেন।
ডন হ্যাচ

2

ব্যবহার scriptআপনার স্ক্রিপ্টে কমান্ডটি (ম্যান 1 স্ক্রিপ্ট)

স্ক্র্যাপ () সেট আপ করে এমন একটি মোড়কের শেলসক্রিপ্ট (2 লাইন) তৈরি করুন এবং তারপরে প্রস্থানটি কল করুন।

পর্ব 1: wrap.sh

#!/bin/sh
script -c './realscript.sh'
exit

পার্ট 2: রিয়েলসক্রিপ্ট.শ

#!/bin/sh
echo 'Output'

ফলাফল:

~: sh wrap.sh 
Script started, file is typescript
Output
Script done, file is typescript
~: cat typescript 
Script started on fr. 12. des. 2008 kl. 18.07 +0100
Output

Script done on fr. 12. des. 2008 kl. 18.07 +0100
~:

1

স্ট প্রোগ্রামের জন্য টি প্রোগ্রাম এবং ডুপ স্ট্যাডার ব্যবহার করুন।

 program 2>&1 | tee > logfile

1

আমি "রানস্ক্রিপ্ট.শ" নামে একটি স্ক্রিপ্ট তৈরি করেছি। এই লিপির বিষয়বস্তু হ'ল:

${APP_HOME}/${1}.sh ${2} ${3} ${4} ${5} ${6} 2>&1 | tee -a ${APP_HOME}/${1}.log

আমি এটিকে এভাবে বলেছি:

./RunScript.sh ScriptToRun Param1 Param2 Param3 ...

এটি কাজ করে তবে এটির বাহ্যিক স্ক্রিপ্টের মাধ্যমে অ্যাপ্লিকেশনটির স্ক্রিপ্টগুলি চালানো দরকার। এটা কিছুটা ক্লডগি।


9
আপনি ites 1 $ 2 $ 3 দিয়ে সাদা স্থান যুক্তি যুক্ত করার গোষ্ঠী হারাবেন ... , আপনার ব্যবহার করা উচিত (ডাব্লু / কোটস): "$ @"
এনভিআরএম

1

এক বছর পরে, এখানে কিছু লগ করার জন্য একটি পুরাতন বাশ স্ক্রিপ্ট। উদাহরণস্বরূপ,
teelog make ...উত্পন্ন লগ নামের লগগুলি (এবং নেস্টেড লগিংয়ের কৌশলটিও দেখুন make))

#!/bin/bash
me=teelog
Version="2008-10-9 oct denis-bz"

Help() {
cat <<!

    $me anycommand args ...

logs the output of "anycommand ..." as well as displaying it on the screen,
by running
    anycommand args ... 2>&1 | tee `day`-command-args.log

That is, stdout and stderr go to both the screen, and to a log file.
(The Unix "tee" command is named after "T" pipe fittings, 1 in -> 2 out;
see http://en.wikipedia.org/wiki/Tee_(command) ).

The default log file name is made up from "command" and all the "args":
    $me cmd -opt dir/file  logs to `day`-cmd--opt-file.log .
To log to xx.log instead, either export log=xx.log or
    $me log=xx.log cmd ...
If "logdir" is set, logs are put in that directory, which must exist.
An old xx.log is moved to /tmp/\$USER-xx.log .

The log file has a header like
    # from: command args ...
    # run: date pwd etc.
to show what was run; see "From" in this file.

Called as "Log" (ln -s $me Log), Log anycommand ... logs to a file:
    command args ... > `day`-command-args.log
and tees stderr to both the log file and the terminal -- bash only.

Some commands that prompt for input from the console, such as a password,
don't prompt if they "| tee"; you can only type ahead, carefully.

To log all "make" s, including nested ones like
    cd dir1; \$(MAKE)
    cd dir2; \$(MAKE)
    ...
export MAKE="$me make"

!
  # See also: output logging in screen(1).
    exit 1
}


#-------------------------------------------------------------------------------
# bzutil.sh  denisbz may2008 --

day() {  # 30mar, 3mar
    /bin/date +%e%h  |  tr '[A-Z]' '[a-z]'  |  tr -d ' '
}

edate() {  # 19 May 2008 15:56
    echo `/bin/date "+%e %h %Y %H:%M"`
}

From() {  # header  # from: $*  # run: date pwd ...
    case `uname` in Darwin )
        mac=" mac `sw_vers -productVersion`"
    esac
    cut -c -200 <<!
${comment-#} from: $@
${comment-#} run: `edate`  in $PWD `uname -n` $mac `arch` 

!
    # mac $PWD is pwd -L not -P real
}

    # log name: day-args*.log, change this if you like --
logfilename() {
    log=`day`
    [[ $1 == "sudo" ]]  &&  shift
    for arg
    do
        log="$log-${arg##*/}"  # basename
        (( ${#log} >= 100 ))  &&  break  # max len 100
    done
            # no blanks etc in logfilename please, tr them to "-"
    echo $logdir/` echo "$log".log  |  tr -C '.:+=[:alnum:]_\n' - `
}

#-------------------------------------------------------------------------------
case "$1" in
-v* | --v* )
    echo "$0 version: $Version"
    exit 1 ;;
"" | -* )
    Help
esac

    # scan log= etc --
while [[ $1 == [a-zA-Z_]*=* ]]; do
    export "$1"
    shift
done

: ${logdir=.}
[[ -w $logdir ]] || {
    echo >&2 "error: $me: can't write in logdir $logdir"
    exit 1
    }
: ${log=` logfilename "$@" `}
[[ -f $log ]]  &&
    /bin/mv "$log" "/tmp/$USER-${log##*/}"


case ${0##*/} in  # basename
log | Log )  # both to log, stderr to caller's stderr too --
{
    From "$@"
    "$@"
} > $log  2> >(tee /dev/stderr)  # bash only
    # see http://wooledge.org:8000/BashFAQ 47, stderr to a pipe
;;

* )
#-------------------------------------------------------------------------------
{
    From "$@"  # header: from ... date pwd etc.

    "$@"  2>&1  # run the cmd with stderr and stdout both to the log

} | tee $log
    # mac tee buffers stdout ?

esac

আমি জানি যে কোনও মন্তব্য যোগ করতে দেরি হচ্ছে তবে আমাকে এই স্ক্রিপ্টটির জন্য ধন্যবাদ বলতে হয়েছিল। খুব দরকারী এবং ভাল নথিভুক্ত!
স্টেফেন মিম

ধন্যবাদ @ স্টেফেন্ম্ম; এটা কখনোই "দরকারী" বা "উন্নত করা যেতে পারে" বলে দেরি।
ড্যানিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.