ভেরিয়েবল হিসাবে কীভাবে 2> / দেব / নাল পাস করবেন?


13

আমার এই কোডটি কার্যকর হয়:

# Hide irrelevant errors so chrome doesn't email us in cron
if [[ $fCron == true ]] ; then
    google-chrome --headless --disable-gpu --dump-dom \
        "$RobWebAddress" > "$DownloadName" 2>/dev/null
else
    # Get silly error messages when running from terminal
    google-chrome --headless --disable-gpu --dump-dom \
        "$RobWebAddress" > "$DownloadName"
fi

আমি যদি এটির মতো করে ছোট করার চেষ্টা করি:

# Hide irrelevant errors so chrome doesn't email us in cron
local HideErrors
[[ $fCron == true ]] && HideErrors="2>/dev/null"

google-chrome --headless --disable-gpu --dump-dom \
    "$RobWebAddress" > "$DownloadName" "$HideErrors"

আমি ত্রুটির বার্তা পেয়েছি:

[0826/043058.634775:ERROR:headless_shell.cc(597)] Open multiple tabs is only supported when remote debugging is enabled.
[0826/043058.672587:ERROR:headless_shell.cc(597)] Open multiple tabs is only supported when remote debugging is enabled.
[0826/043058.711640:ERROR:headless_shell.cc(597)] Open multiple tabs is only supported when remote debugging is enabled.
(... SNIP ...)

একটি হার্ড-কোডেড যুক্তি কেন চলক হিসাবে তর্ক হিসাবে কাজ করে না?


সম্পাদনা 2:

বর্তমানে আমি দ্বিতীয় উত্তরের বিকল্প পরামর্শ দিয়ে সাফল্য পেয়েছি:

# Redirect errors when cron is used to /dev/null to reduce emails
ErrorPipe=/dev/stderr
[[ $fCron == true ]] && ErrorPipe=/dev/null

google-chrome --headless --disable-gpu --dump-dom \
                "$RobWebAddress" > "$DownloadName" 2>"$ErrorPipe"

সম্পাদনা 1:

প্রথম উত্তরের উপর ভিত্তি করে, আমার কাছে প্রোগ্রাম শিরোনামটিতে ইতিমধ্যে রয়েছে:

[[ $fCron != true ]] &&
    exec 2> >(grep -v 'GtkDialog mapped without a transient parent' >&2)

আপনি তার [[ $fCron == true ]] && exec 2>/dev/nullপরিবর্তে চেষ্টা করতে পারেন
স্টিল্ড্রাইভার

.. মোটামুটি কথা বলছি, কারণ শেলটি ভেরিয়েবলগুলি প্রসারণের আগে পুনর্নির্দেশগুলি সেট করে। উদাহরণস্বরূপ বাশ দেখুন:
স্ট্যাডার স্টোরআউট

উত্তর:


19

আপনি প্রসারিত হয়ে পুনঃনির্দেশের কারণ ঘটতে না পারার কারণটি "$HideErrors"হ'ল প্যারামিটার বিস্তৃতি> দ্বারা উত্পাদিত হওয়ার পরে যেমন প্রতীকগুলি বিশেষভাবে চিকিত্সা করা হয় না । এটি প্রকৃতপক্ষে খুব ভাল, কারণ এই জাতীয় চিহ্নগুলি পাঠ্যে প্রদর্শিত হবে যা আপনি আক্ষরিকভাবে প্রসারিত করতে এবং ব্যবহার করতে চাইতে পারেন।

এটি আপনার উদ্ধৃতি কিনা তা ধরে রাখে $HideErrors। প্যারামিটার প্রসারণের ফলাফলটি শব্দ বিভাজন এবং গ্লোব্বিংয়ের সাপেক্ষে যখন সম্প্রসারণটি অব্যক্ত থাকে, তবে এটি।


এটি সম্পর্কে কী করা উচিত, শর্তসাপেক্ষে পুনঃনির্দেশটি অর্জনের অসংখ্য উপায় রয়েছে। খুব সাধারণ কমান্ডের জন্য, পুরো কমান্ডটি দু'বার লিখতে যুক্তিযুক্ত হতে পারে, একবার caseবা if- elseকনস্ট্রাক্টের প্রতিটি শাখায় একবার । এটি শীঘ্রই বোঝা হয়ে ওঠে, এবং আপনি যে আদেশটি দেখিয়েছেন তা অবশ্যই এমন একটি ঘটনা যেখানে এটি আদর্শ হবে না।

আপনার নিজের পুনরাবৃত্তি এড়াতে দেয় এমন পদ্ধতির মধ্যে দুটি বিশেষত আমি বিশেষ করে সুপারিশ করি কারণ এগুলি বেশ পরিষ্কার এবং সঠিকভাবে পাওয়া সহজ। আপনি একই কমান্ড এবং পুনঃনির্দেশের জন্য একবারে নয়, এর মধ্যে একটিরও ব্যবহার করতে চান।

পুনর্নির্দেশের পরিবর্তে কমান্ডটি সঞ্চয় করুন। পুনঃনির্দেশটি একটি ভেরিয়েলেলে সংরক্ষণ করার চেষ্টা করার পরিবর্তে এবং পরামিতি প্রসারণ প্রয়োগ করার পরিবর্তে শেল ফাংশনে কমান্ডটি সংরক্ষণ করুন । তারপরে একটি caseবা if- লিখুন else, যাতে ফাংশনটি একটি শাখায় পুনর্নির্দেশের সাথে এবং অন্যটিতে ছাড়াই ডাকা হয়।

আপনি যদি আপনার কমান্ডটি কোড হিসাবে কল্পনা করেন যা আপনি একবার লিখতে চান তবে একাধিক পরিস্থিতিতে চালিত হন, তবে একটি ফাংশন হ'ল প্রাকৃতিক সমাধান। আমি সাধারণত এটিই করি। এটা তন্ন তন্ন একটি প্রয়োজন সুবিধা রয়েছে subshell কিংবা ম্যানুয়াল স্টোরেজ এবং রাষ্ট্র রিসেট।

আপনার কোড সহ:

launch() {
    google-chrome --headless --disable-gpu --dump-dom \
        "$RobWebAddress" > "$DownloadName"
}

case $fCron in
true)  launch 2>/dev/null;;
*)     launch;; # Get silly error messages when running from terminal
esac

আপনার পছন্দসই ফাঁকা জায়গাগুলি আপনি প্রয়োগ করতে পারেন বা if- এর elseপরিবর্তে আপনি যদি পছন্দ করেন তবে। নোট করুন যে launchকলার RobWebAddressএবং DownloadNameভেরিয়েবলগুলি স্বয়ংক্রিয়ভাবে তারা স্থানীয় ভেরিয়েবলগুলি ব্যবহার করে, কারণ বাশ গতিশীলভাবে স্কোপযুক্ত , বেশিরভাগ প্রোগ্রামিং ভাষার থেকে ভিন্ন যা লাক্ষিকভাবে স্কোপযুক্ত।

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

(স্ট্যান্ডার্ড ত্রুটিটি কী ছিল তা ট্র্যাক করে রাখা এবং এটি পুনরুদ্ধার করা সম্ভব, সাবসেল ব্যবহার না করে এবং এইভাবে বর্তমান শেলের পরিবেশ পরিবর্তন করার ক্ষমতাকে ত্যাগ না করে I'll

আপনার কোড সহ:

(
    # Suppress silly error messages unless running from terminal
    case $fCron in true) exec 2>/dev/null;; esac

    google-chrome --headless --disable-gpu --dump-dom \
        "$RobWebAddress" > "$DownloadName"
)

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

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


এফওয়াইআই স্টিলড্রাইভার execসে সম্পর্কে কোনও উত্তর দেওয়ার পরিকল্পনা করছেন কিনা তা জানেন না সে সম্পর্কে কিছু উল্লেখ করেছেন ...
উইনউনুচস

@ WinEunuuchs2 ইউনিক্স আমি আশা করি এরকম উত্তর এখনও পোস্ট করা আছে। যদিও আমি মূলত কোনও ফাংশন ব্যবহার করার পরামর্শ দিই, আমি আবার একটি পুনর্নির্দেশ জড়িত একটি পদ্ধতিও অন্তর্ভুক্ত করেছি exec। তবে, যেমন আমি পৈত্রিকভাবে উল্লেখ করেছি, আমি আরও পরিশীলিত অ্যাপ্লিকেশনগুলি কভার করিনি যেখানে পুরানো ফাইল বর্ণনাকারী সাবস্কেল ছাড়াই রাখা এবং পুনরুদ্ধার করা হয়। আমি কম পরিশীলিত অ্যাপ্লিকেশনগুলিও কভার করিনি , যেমন স্ক্রিপ্টের শেষ যদি ঠিক হয় তবে পুনর্নির্দেশটি রাখা। আরেকটি উত্তর, পোস্ট করা থাকলে উভয়কেই coverেকে রাখতে পারে এবং সম্ভবত আরও কিছু।
এলিয়াহ কাগন

আমি আমার প্রশ্নটি একটি বিদ্যমান দিয়ে আপডেট করেছি execযা আপনার উত্তরটিকে আমার মনে হয় এমনভাবে প্রভাবিত করে না।
WinEunuuchs2Unix

@ WinEunuuchs2 ইউনিক্স হ্যাঁ, এটি কোনও সমস্যা হওয়া উচিত নয়। আমি উত্তরের শেষে এটি সম্পর্কে একটি অনুচ্ছেদ যুক্ত করেছি।
এলিয়াহ কাগন

আপনার উত্তর পড়ার আকর্ষণীয় উদ্ঘাটন, RobWebAddressঅবশ্যই বিশ্বব্যাপী প্রসঙ্গ। DownloadNameস্থানীয় সংজ্ঞায়িত করা হয়েছিল তবে এটি বৈশ্বিক প্রেক্ষাপটে হওয়া উচিত। কোনও কারণে শিশু ফাংশনগুলি পিতামাতার স্থানীয় সংজ্ঞার অধিকারী হয় ( স্থানীয়ভাবে এটি সংজ্ঞায়িত করা ফাংশন দ্বারা বুদ্ধিমানভাবে DownloadNameদৃশ্যমান ছিল । এটি একটি মোটামুটি দিন হয়ে গেছে :(DownloadAsHTML ()UpdateOne ()
উইনউনুচস 2 ইউনিক্স

4

একটি হার্ড-কোডেড যুক্তি কেন চলক হিসাবে তর্ক হিসাবে কাজ করে না?

কারণ সিনট্যাক্স আইটেমগুলি বর্ধিত পরিবর্তনশীল মানগুলির দ্বারা ব্যাখ্যা করা হয় না। অর্থাৎ, ভেরিয়েবল প্রসারণ কমান্ড লাইনে ভেরিয়েবলের পাঠ্যের সাথে পরিবর্তনশীল রেফারেন্সটি প্রতিস্থাপনের মতো নয়। (স্টাফ মত ;, |, &&এবং কোট ইত্যাদি এছাড়াও ভেরিয়েবলের মান বিশেষ হয় না।)

আপনি যা করতে পারেন তা হ'ল এলিয়াস ব্যবহার করা বা পুনঃনির্দেশের কেবলমাত্র লক্ষ্য ধরে রাখতে ভেরিয়েবলটি ব্যবহার করা।

ওরফে হয় যাতে তারা শুধু একটি টেক্সট প্রতিস্থাপন করতে অন্বিত আইটেম, অপারেটার এবং কীওয়ার্ড মত করে ধরে রাখুন। একটি স্ক্রিপ্টে, আপনার প্রয়োজন হবে shopt expand_aliases, যেহেতু ডিফল্টরূপে এগুলি ইন্টারঅ্যাক্টিভ শেলগুলিতে অক্ষম। সুতরাং, এই প্রিন্টগুলি 2(কেবল):

#!/bin/bash
shopt -s expand_aliases

alias redir='> /dev/null'
redir echo 1
alias redir=''
redir echo 2

(এবং আপনি alias jos=if niin=then soj=fiএবং তারপরে আপনার সমস্ত বিবৃতি ফিনিশ ভাষায় লিখতে পারেন I'm আমি নিশ্চিত যে স্ক্রিপ্টটি পড়া কেউ আপনাকে পছন্দ করবে))

বিকল্পভাবে, সবসময় পুনর্নির্দেশটি লিখুন, তবে কেবল একটি ভেরিয়েবলের সাথে লক্ষ্য নিয়ন্ত্রণ করুন। আপনি যেখানে আউটপুট যায় কেস যেখানে আপনি পরিবর্তন করতে চাই না একটি নো-অপ লক্ষ্য প্রয়োজন যদিও করব কিন্তু /dev/stderrযে ক্ষেত্রে কাজ করা উচিত। প্রকৃতপক্ষে, 2> /dev/stderrলিনাক্সটি এফডি /proc/<pid>/fdআসল থেকে স্বতন্ত্র থেকে খুলার যেভাবে আচরণ করে তার কারণে যোগ করা কোনও বিকল্প নেই । এটি লেখার অবস্থানের অবস্থানকে প্রভাবিত করে এবং যদি এটি একটি নিয়মিত ফাইলে যায় তবে আউটপুট গোলমাল করবে।

এটি অ্যাপেন্ড মোডে কাজ করা উচিত, যদিও (বা স্ট্ডার পাইপ বা টার্মিনালে যায়):

#!/bin/sh
exec 2>/tmp/error.log
dst=/dev/null
ls -l /nosuchfile-1 2>> "$dst"     # this doesn't print
dst=/dev/stderr
ls -l /nosuchfile-2 2>> "$dst"
ls -l /nosuchfile-3 2>> "$dst"

সুতরাং পুনরাবৃত্তি: 2> /dev/stderrবিরতি করতে পারেন।


হাহাহা, আমি এখন থেকে কাজের ফিনিশ আইফএস ব্যবহার করব। :>
মিষ্টি

আমি বিকল্প পরামর্শ পছন্দ করি। expand_aliasesভাবনাটি ভীতিজনক কারণ আপনার ধারণাটি আপনার প্রোগ্রামটি জিম্মি করে রাখা যেতে পারে ~/.bashrc
WinEunuuchs2 ইউনিক্স

1
@ WinEunuuchs2 ইউনিক্স, হ্যাঁ, expand_aliasesকিছুটা ভীতিজনক। তবে ~/.bashrcএটি কোনও সমস্যা হবেনা কারণ এটি কেবল ইন্টারেক্টিভ শেলগুলিই পড়ে .profileএবং যে বন্ধুরা এটি কল করতে পারে কেবল লগইন শেল দ্বারা সেগুলি পড়ে। স্ক্রিপ্টগুলির মতো নন-ইন্টারেক্টিভ অ-লগইন শেলগুলির মধ্যে কোনওটি চালানো উচিত নয়। (তবে তারপরেও রয়েছে $BASH_ENV, এবং .bashrc
স্পিডিনটি

ঠিক আছে, আমি আপনার বিকল্প পরামর্শটি পুরোপুরি বুঝতে পেরেছি এবং আমি আজ রাতেই এটি চেষ্টা করব :)
WinEunuuchs2Unix

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

1

প্রশ্নের শিরোনাম: "ভেরিয়েবল হিসাবে 2> / ডি / নাল কীভাবে পাস করবেন?" এটি আসলে ব্যবহার করে করা যেতে পারেeval

joshua@nova:/tmp$ X=">/dev/null"
joshua@nova:/tmp$ echo $X
>/dev/null
joshua@nova:/tmp$ eval echo $X
joshua@nova:/tmp$ eval echo hi
hi
joshua@nova:/tmp$ eval echo hi $X
joshua@nova:/tmp$ echo hi $X
hi >/dev/null
joshua@nova:/tmp$ 

সুতরাং আমরা হিসাবে লিখতে পারেন

# Hide irrelevant errors so chrome doesn't email us in cron
local HideErrors
local RobWebAddress2
local DownloadName2
[[ $fCron == true ]] && HideErrors="2>/dev/null"
RobWebAddress2='"$RobWebAddress"'
DownloadName2='>"$DownloadName"'

eval google-chrome --headless --disable-gpu --dump-dom \
    $RobWebAddress2 $DownloadName2 "$HideErrors"

যেখানে অপ্রত্যক্ষ ভেরিয়েবল অ্যাক্সেসটি কমান্ড লাইনের বাকী অংশে খুব শীঘ্রই ঘটতে বাধা দেয়।

ভেরিয়েবলগুলিতে ডাবল উদ্ধৃতিগুলি ঠিক কাজ করে।

joshua@nova:/tmp$ X='"'
joshua@nova:/tmp$ Y='$X'
joshua@nova:/tmp$ eval echo $Y
"
joshua@nova:/tmp$ 

@ এলিয়াকাগান: প্রশ্নের শিরোনাম: "ভেরিয়েবল হিসাবে কীভাবে 2> / ডিভ / নাল পাস করবেন?"
জোশুয়া

ঠিক আছে এটি কাজ করে না। আমি এটি স্থির করেছি।
জোশুয়া

এখন ফাইলটি সর্বদা নাম দেওয়া হয় DownloadName- এবং আক্ষরিক পাঠ্যটি RobWebAddressসর্বদা ইউআরএল এর জন্য ব্যবহৃত হয়। আপনি $" "উদ্ধৃতি ব্যবহার করছেন । আমি মনে করি এটি অনিচ্ছাকৃত হতে পারে এবং আপনি এটির $অভ্যন্তরের অভ্যন্তরটি চাইতে পারেন " "তবে আপনি উভয় জায়গায় সেভাবে করেছিলেন তাই আমি নিশ্চিত নই। আমি মনে করি এটি ঠিক করা > "$DownloadName"উচিত। তবে আমি বুঝতে পারি যে আপনি এটি পছন্দ করতে পারেন না, যেহেতু দুর্ঘটনাক্রমে যুক্তি এবং অ-তর্কগুলির সাথে evalমিশ্রণ এটির বিপজ্জনক এবং ব্যাপকভাবে হতাশার evalআচরণকে ব্যবহার করতে নিরুৎসাহিত করার একটি কারণ ।
এলিয়াহ কাগন

@ এলিয়াকাগান: ওহ। স্ক্রিপ্টিংয়ের জন্য আমার পছন্দসই শেলটির উদ্ধৃতি নেই ing ""।
জোশুয়া

1
যদি আপনি এটি ঠিক করেন তবে এটি কাজ করা উচিত। এবং আমি এটি সর্বদা ভুল মনে করে এটি স্বেচ্ছাসেবী পাঠ্যের উপর কোটগুলি আটকে দিয়েছি! এটি আক্ষরিক আর্গুমেন্ট তৈরি করে যা evalমূল্যায়ন করার আগে সম্মিলিত করে। তবে আমি মনে করি এটির আরেকটি উপায় হ'ল এটি লিখিতভাবে একটি অপ্রচলিত উপায় যা ওপির কোডের চেহারাটির সাথে eval 'google-chrome --headless --disable-gpu --dump-dom "$RobWebAddress" > "$DownloadName" '"$HideErrors"সাদৃশ্যপূর্ণ । এবং সাধারণভাবে, যে কাজের প্রয়োজন হয় না তার জন্য ব্যবহার করা খারাপ(এই অজুহাতগুলির কোনওটিই - না এমনকি ব্যাখ্যাও দেয় না - আমার পুরানো জবাবের ভুল এবং শত্রুতা।)eval
এলিয়াহ কাগন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.