শেল স্ক্রিপ্টে $ {1 + "$ @" What এর অর্থ কী এবং এটি "$ @" থেকে কীভাবে আলাদা?


43

পার্ল ডকুমেন্টেশনে, পার্লরুন (1) দ্বিভাষিক শেল / পার্ল শিরোনাম ব্যবহার করে পার্ল স্ক্রিপ্টগুলি চালু করার পরামর্শ দেয়:

#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS $0 ${1+"$@"}'
    if 0;

কী ${1+"$@"}মানে? আমি "$@"পরিবর্তে (বাশকে / বিন / শ হিসাবে ব্যবহার করে) ব্যবহার করার চেষ্টা করেছি এবং এটি ঠিক তেমন কাজ করে বলে মনে হচ্ছে।


সম্পাদন করা

নীচে দুটি উত্তর বলে যে এটি হওয়ার কথা ${1:+"$@"}। আমি ${parameter:+word}ব্যাশ (1) এ নথিভুক্ত ("বিকল্প মান ব্যবহার করুন") সিনট্যাক্স সম্পর্কে সচেতন । যাইহোক, আমি অপ্রকাশিত, কারণ

  1. উভয় ${1+"$@"}এবং "$@"ঠিক সূক্ষ্মভাবে কাজ করে, এমনকি কোনও প্যারামিটার না থাকলেও। যদি আমি সরল.শ তৈরি করি

    #!/bin/sh
    eval 'exec /usr/bin/perl -x -S -- $0 "$@"'
        if 0;
    #!perl
    use Data::Dumper;
    print Dumper(\@ARGV);

    এবং প্রশ্ন.শ হিসাবে

    #!/bin/sh
    eval 'exec /usr/bin/perl -x -S -- $0 ${1+"$@"}'
        if 0;
    #!perl
    use Data::Dumper;
    print Dumper(\@ARGV);

    আমি উভয়কে অভিন্নভাবে কাজ করতে পারি:

    $ ./question.sh 
    $VAR1 = [];
    $ ./question.sh a
    $VAR1 = [
              'a'
            ];
    $ ./question.sh a 'b c'
    $VAR1 = [
              'a',
              'b c'
            ];
    $ ./question.sh ""
    $VAR1 = [
              ''
            ];
    $ ./simple.sh 
    $VAR1 = [];
    $ ./simple.sh a
    $VAR1 = [
              'a'
            ];
    $ ./simple.sh a 'b c'
    $VAR1 = [
              'a',
              'b c'
            ];
    $ ./simple.sh ""
    $VAR1 = [
              ''
            ];
  2. ইন্টারনেটে অন্যান্য উত্সগুলিও এমন হ্যাকার${1+"$@"} সহ ব্যবহার করে যা দেখে মনে হয় যে সে কী করছে।

সম্ভবত ${parameter+word}একটি অনথিভুক্ত বিকল্প (বা অবচয়) সিনট্যাক্স এর জন্য ${parameter:+word}? কেউ কি এই হাইপোথিসিস নিশ্চিত করতে পারে?


উত্তর:


53

এটি বোর্ন শেলের সাথে সামঞ্জস্যের জন্য। বোর্ন শেলটি একটি পুরাতন শেল যা ১৯৯৯ সালে ইউনিক্স সংস্করণ with সহ প্রথম প্রকাশিত হয়েছিল এবং 90 এর দশকের মাঝামাঝি পর্যন্ত /bin/shবেশিরভাগ বাণিজ্যিক ইউনিকে হিসাবে এটি সাধারণ ছিল ।

এটা তোলে অধিকাংশ পূর্বপুরুষ বোর্ন মত শাঁস মত ksh, bashবা zsh

এতে কয়েকটি বিশ্রী বৈশিষ্ট্য ছিল যার মধ্যে অনেকগুলি ঠিক করা হয়েছে kshএবং অন্যান্য শেল এবং এর নতুন মান স্পেসিফিকেশন shরয়েছে যার মধ্যে একটি হ'ল:

বোর্ন শেল দিয়ে (কমপক্ষে সেই রূপগুলি যেখানে এটি স্থির করা হয়নি): "$@"কোনও খালি যুক্তির $# == 0পরিবর্তে অবস্থানগত পরামিতিগুলির তালিকা খালি ( ) খালি থাকলে একটি খালি যুক্তিতে প্রসারিত হয় ।

${var+something}$varসেট না করা থাকলে "কিছুতে" প্রসারিত হয় । এটি সমস্ত শেলগুলিতে স্পষ্টভাবে নথিবদ্ধ তবে bashডকুমেন্টেশনে এটি খুঁজে পাওয়া শক্ত কারণ আপনার এই বাক্যটির দিকে নজর দেওয়া দরকার:

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

সুতরাং কেবল সেট করা থাকলে ${1+"$@"}প্রসারিত হয় ( ) যা বোর্ন শেলটির সীমাবদ্ধতার চারপাশে কাজ করে।"$@"$1$# > 0

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

সেই perlrunপার্ল্ডোক পাতায় একটি সমস্যা রয়েছে $0যদিও তা উদ্ধৃত হয়নি।

আরও তথ্যের জন্য http://www.in-ulm.de/~mascheck/various/bourne_args/ দেখুন ।


উত্তরাধিকারী পুনরুত্পাদন করতে পারবেন না। সম্ভবত সোলারিসের জন্য প্রযোজ্য নয়।
ormaaj

2
@ormaaj। হ্যাঁ, আমি সংযুক্ত পৃষ্ঠাটি দেখুন। এটি এসভিআর 3 এ স্থির করা হয়েছিল, এবং সোলারিস / সুনোস 5 এর উপরে এসভিআর 4 এ রিবাসেড হয়েছিল। এবং সেই পৃষ্ঠাটিতে উল্লেখ করা হয়েছে যে 4.1.x এ সমস্যাটিও ছিল না।
স্টাফেন চেজেলাস 21 '21

আহ আমি দেখি. <3 পৃষ্ঠাগুলি মাসচেক করুন।
ormaaj

3

এর মধ্যে পার্থক্য রয়েছে:

command ""

এবং

command

একটিতে, আপনি একটি যুক্তিটি যাচ্ছেন যা খালি স্ট্রিং। দ্বিতীয়টিতে শূন্য আর্গুমেন্ট পাস হয়েছে।

উভয় জন্য, "$ @" একই জিনিস সমার্থক হবে: ""। কিন্তু ব্যবহার ${1:+"$@"}হবে ""প্রথম ও কোন যুক্তি দ্বিতীয়, যা অভিপ্রায় ছিল গৃহীত জন্য।

আপনি যদি নীচে স্ক্রিপ্ট করে থাকেন তবে এটি গুরুত্বপূর্ণ হয়ে উঠবে, তাকে বলা হয় sshwrapper, যা আপনি একটি alচ্ছিক কমান্ড দিয়ে কল করেন বা কোনও ইন্টারেক্টিভ শেল পাওয়ার জন্য কোনও যুক্তি দিয়ে নেই।

: sshwrapper [command]
exec /usr/bin/ssh "${HOSTNAME:-localhost}" "$@"

এটি দূরবর্তী হোস্টে "" চালানোর চেষ্টা করবে (যা কেবল ফিরে আসে), এটি ইন্টারেক্টিভ শেল হবে না।

: sshwrapper [command]
exec /usr/bin/ssh "${HOSTNAME:-localhost}" ${1:+"$@"}

রিমোট হোস্টে একটি ইন্টারেক্টিভ শেল শুরু করবে কারণ এক্সিকিউটিটি ভেরিয়েবলকে সঠিকভাবে কিছু হিসাবে ব্যাখ্যা করবে, খালি স্ট্রিং নয়।

"$ {প্যারামিটার: + শব্দ}" ("বিকল্প মান ব্যবহার করুন") এবং ব্যাশ ম্যানুয়াল পৃষ্ঠাগুলিতে অনুরূপ পরিবর্তনশীল প্রসারণের স্ট্রিংয়ের ব্যবহার সম্পর্কে পড়ুন।


এই শুধুমাত্র বোর্ন শেল এবং প্রয়োগ বলে মনে হয় না কোন POSIX-conformant জন্য shবাস্তবায়ন (অন্যান্য উত্তর দেখুন)।
törzsmókus

4
না, খালি ${1:+"$@"}থাকলে কোনও যুক্তিতে প্রসারিত হবে $1। আপনি চান ${1+"$@"}। মূলত আপনি এটি বিপরীত হয়েছে।
স্টাফেন চেজেলাস

0

আমি স্টাফেন চেজেলাসের উত্তরটির সংক্ষিপ্তসার জানিয়েছি:

  • $ {1: + "$ @"} 'পরীক্ষা যদি $ 1 টি বাতিল বা সেট না করে থাকে
  • $ 1 আনসেট না করা থাকলে $ {1 + "$ @"} 'পরীক্ষা করুন

সুতরাং যদি দ্বিতীয়টির সাথে প্যারামিটার ব্যবহার করে "", তার অর্থ $ 1 টি নাল, তবে এটি নাল বা না তা পরীক্ষা করে না, এটি কেবল এটি খালি আছে কি না তা ইতিমধ্যে সেট করা হয়েছে তা দেখে এটি প্রসারিত হবে $ @ , তবে আপনি "" দিয়ে $ {1: + "$ @" "} 'ব্যবহার করেন, এটি আর প্রসারিত হবে না $@


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