বাশ: স্টডারর | স্টডআউট পুনঃনির্দেশ সংরক্ষণ করার জন্য একটি পরিবর্তনশীল ব্যবহার করুন


17

স্ক্রিপ্টে কমান্ড অপশন যুক্ত করার মতো ভেরিয়েবলের মাধ্যমে স্টডআউট এবং স্টডারকে পুনঃনির্দেশ করার কোনও উপায় আছে কি?

উদাহরণস্বরূপ আমার কাছে একটি স্ক্রিপ্ট রয়েছে:

#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
mkdir $OPT 123/123/123 $TEST

আমি দেখতে পাচ্ছি যে ওপিটি -pকোনও সমস্যা ছাড়াই প্রতিস্থাপন করা হয়েছে এবং ব্যাশ এটি বিকল্প হিসাবে ব্যাখ্যা করে। তবে পুনঃনির্দেশ ডিরেক্টরি নাম হিসাবে ব্যাখ্যা করে।

$ ./test.sh 
+ TEST='>/dev/null 2>&1'
+ OPT='-p -v'
+ mkdir -p -v 123/123/123 '>/dev/null' '2>&1'
mkdir: created directory `123/123'
mkdir: created directory `123/123/123'
mkdir: created directory `>/dev'
mkdir: created directory `>/dev/null'
mkdir: created directory `2>&1'

বাশ বলতে কি কোনও উপায় আছে, that ভিএআর পুনর্নির্দেশনা, কোনও ডায়ারের নাম নয়।

পুনশ্চ. হতে পারে আমি ভুল পথে আছি তবে আমি আমার স্ক্রিপ্ট থেকে alচ্ছিক ভার্বোস বা নন ভার্বোজ আউটপুট তৈরি করতে চাই। তবে আমার অ-ভার্বোস মোডেও কিছু আউটপুট প্রয়োজন, অতএব আমি কেবল আমার স্ক্রিপ্টের ভিতরে কিছু কমান্ড থেকে পুরো স্ট্ডআউট এবং স্টডারকে পুনঃনির্দেশ করতে পারি না।

উত্তর:


18

আর একটি সমাধান নিম্নলিখিত হতে পারে:

#!/bin/bash

verbose=0

exec 3>&1
exec 4>&2

if ((verbose)); then
  echo "verbose=1"
else
  echo "verbose=0"
  exec 1>/dev/null
  exec 2>/dev/null
fi

echo "this should be seen if verbose"
echo "this should always be seen" 1>&3 2>&4

তারপরে 1>&3 2>&4আপনি যে কমান্ডগুলি আউটপুট দেখতে চান তা কেবল যুক্ত করুন ।


গ্রেট। আমি ঠিক এই জিনিসটি দেখেছি। ধন্যবাদ.
নলখাগড়া

এটি কীভাবে কাজ করে তা
বোঝাতে

5

অন্যান্য উত্তরে "কীভাবে" ভালভাবে ব্যাখ্যা করা হয়েছে; আমি "কেন" ওপির কোডটি কাজ করে না তা সম্বোধন করতে চাই।

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

অন্য কথায়, একবার ভেরিয়েবলগুলি প্রসারিত হলে পুনঃনির্দেশের অক্ষর ( <বা >, ইত্যাদি) বিবেচনার জন্য এটি "খুব দেরী" হয়ে গেছে, কারণ শেলটি কমান্ড স্ট্রিংয়ের কোন অংশটি পুনঃনির্দেশ হিসাবে পরিচালনা করতে চলেছে তা ইতিমধ্যে চিহ্নিত করেছে।

আরও পড়ার জন্য, নীচে তালিকাভুক্ত 1 এবং 3 পদক্ষেপ দেখুন:

LESS='+/^SIMPLE COMMAND EXPANSION' man bash

3

এটি একটি "ডিরেক্টরি নাম" হিসাবে ব্যাখ্যা করছে না, >উদ্ধৃত করা হচ্ছে, সুতরাং এটি আক্ষরিকরূপে চিকিত্সা করা হচ্ছে (আরও সুনির্দিষ্টভাবে আপনি স্ট্রিংটি প্রেরণ করছেন >dev/null 2>&1this আপনার কাছাকাছি আসার একমাত্র উপায় evalএকটি নতুন শেল ব্যবহার করে বা তৈরি করা।

আপনার প্রশ্নটিতে আপনার "ভার্বোজ" ইস্যুটিতে ইঙ্গিত দেওয়া হয়েছে, পরিবর্তে এটি করুন:

verbose=1
if (( verbose )); then
    mkdir -v -p /foo
else
    mkdir -p /foo > /dev/null 2>&1
fi

1

আপনার ভেরিয়েবলগুলিতে আপনার অনেকগুলি স্থান রয়েছে, যা সঠিকভাবে মূল্যায়ন করা হবে না। আপনি evalসেট আপ করতে ব্যবহার করতে চান ।

#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
eval mkdir $OPT 123/123/123 $TEST

এটি $ OPT কে একটি ( ) এর পরিবর্তে দুটি আর্গুমেন্টে ( -pএবং -v) এবং $ টেস্টের সাহায্যে বিভক্ত করতে দেবে -p -v/dev/nullএটি ব্যবহারেও পরিবর্তন হয়েছে কারণ devআপনার বর্তমান ডিরেক্টরিতে ডিরেক্টরি থাকতে পারে এটি খুব কমই ।


0

এনজোটিবের উত্তরে কিছু ভাল ফাইল বর্ণনাকারী যাদু ব্যবহার করা হয়েছে, তবে এর সহজ সমাধানটি কেবল ব্যবহার করা eval লাইন (যা করে অ্যাড প্রক্রিয়া ওভারহেড তবে):

$ rm /tmp/foo
$ ll /tmp/foo
ls: cannot access /tmp/foo: No such file or directory
$ FOO=">/tmp/foo"
$ date $FOO
date: invalid date '>/tmp/foo'
$ cat /tmp/foo
cat: /tmp/foo: No such file or directory
$ eval date $FOO
$ cat /tmp/foo
Thu Dec 13 14:08:17 EST 2018
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.