'যদি [$ 1 = "1"] "শাখাটি সর্বদা $ 1 1 না হলেও কেন নির্বাচিত হয়?


10

আমার কাছে 'টেলিপোর্ট.শ' নামে একটি শেল স্ক্রিপ্ট রয়েছে:

if [ $1="1" ];
    then
    shift
        mv "$@" ~/lab/Sun
elif [ $1="2" ];
    then
    shift
        mv "$@" ~/lab/Moon
elif [ $1="3" ];
    then
    shift
        mv "$@" ~/lab/Earth
fi

যখন আমি কার্যকর করি:

sh teleport.sh 2 testfile

এটি ডিরেক্টরিতে testfileস্থানান্তরিত হয়েছে ~/lab/Sun, যা আমাকে অনেকটা বিভ্রান্ত করে কারণ আমি সেই স্ক্রিপ্টটিতে 1 বা '1' পাস করিনি didn't

এখানে কি সমস্যা?


1
ল্যাব , সূর্য , চাঁদ , পৃথিবী এবং টেলিপোর্টের জন্য +1 । কিন্তু আপনি উচিত সবসময় ডাবল উদ্ধৃতি প্রসারণও ( $var, $(cmd), এবং এমনকি `cmd`[যা $(cmd)পছন্দ করা উচিত])। কিছু প্রান্ত ক্ষেত্রে যেখানে আপনি না আছে উদ্ধৃত করা, কিন্তু সবসময় করছেন এটি আঘাত করা হবে না।
nyuszika7h

@ nyuszika7h, ডাবল উক্তিটির অর্থ "$ var" এবং "$ সেমিডি" হওয়া উচিত নয়? আপনি উপরে উল্লিখিত বৃত্তাকার বন্ধনীটির সুবিধা কী?
জেন

$(cmd)হয় কমান্ড প্রতিকল্পন , (বেশিরভাগই) হিসাবে একই `cmd`। দেখুন mywiki.wooledge.org/CommandSubstitution এবং mywiki.wooledge.org/BashFAQ/082
nyuszika7h

উত্তর:


19

স্পেস ব্যবহার আপনার সমস্যার সমাধান করে।

if [ "$1" = 1 ];
    then
    shift
        mv "$@" ~/lab/Sun
elif [ "$1" = 2 ];
    then
    shift
        mv "$@" ~/lab/Moon
elif [ "$1" = 3 ];
    then
    shift
        mv "$@" ~/lab/Earth
fi

যদিও এটি আরও কম:

#!/bin/bash

action=$1
shift
files=("$@")
case $action in  
  1) mv -- "${files[@]}" ~/lab/Sun     ;;
  2) mv -- "${files[@]}" ~/lab/Moon    ;;
  3) mv -- "${files[@]}" ~/lab/Earth   ;;
esac

3
হ্যাঁ, স্পেসগুলি প্রয়োজনীয়, তবে আমি ভাবছি যে কেন মূল $1="1"সিনট্যাক্সটি মোটেও "কাজ করে" (সত্যিকারের ফলাফল তৈরি করে)। [/ testবিল্টিন কীভাবে সেই অভিব্যক্তিটির ব্যাখ্যা দেয়?
ইক্রিস্টোফারসন

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

2
$1="1"হয় $1দ্বারা ঘনিভূত=1
jdh8

কেস ব্যবহার করার সময়, যখন শর্তগুলির কোনওটিই পূরণ না হয় তখন কীভাবে কার্যকর করতে একটি অ্যাকশন সেট করবেন?
জেন

11

প্রথম সুস্পষ্ট জিনিস আপনি অফ আর্গুমেন্ট মধ্যে শূণ্যস্থান প্রদান করা উচিত নয় [, testঅথবা [[:

if [ "$1" = 1 ];

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

if [[ $1 == 1 ]];

যোগ করা হয়েছে নোট: দ্বিতীয় প্রতীক এছাড়াও ভেরিয়েবল থাকে তবে উদ্ধৃত প্রয়োজনীয় হিসাবে এটি প্যাটার্ন ম্যাচিং হতে পারে যদি আপনি এটা পছন্দ স্বীকৃত অক্ষর রয়েছে *, ?, [], ইত্যাদি .. তাহলে globbing বর্ধিত বা প্যাটার্ন ম্যাচিং সঙ্গে সক্রিয় করা হয় shopt -s extglob, অন্যান্য ধরনের মত @(), !()ইত্যাদি নিদর্শন হিসাবে স্বীকৃত হবে। প্যাটার্ন ম্যাচিং দেখুন ।

অপারেটরগুলির মতো <এবং >এটি এখনও প্রয়োজনীয় হতে পারে কারণ আমি একবার একটি বাগের মুখোমুখি হয়েছিলাম যেখানে দ্বিতীয় যুক্তির উদ্ধৃতি না দেওয়ার ফলে বিভিন্ন ফলাফল হয়েছিল।

প্রথম অপারেন্ড হিসাবে, কিছুই প্রয়োগ হয় না।

এছাড়াও এই সহজ প্রকরণ বিবেচনা করুন:

case "$1" in
1)
    mv -- "${@:2}" ~/lab/Sun
    ;;
2)
    mv -- "${@:2}" ~/lab/Moon
    ;;
3)
    mv -- "${@:2}" ~/lab/Earth
    ;;
esac

বা ঘনীভূত:

case "$1" in
1) mv -- "${@:2}" ~/lab/Sun ;;
2) mv -- "${@:2}" ~/lab/Moon ;;
3) mv -- "${@:2}" ~/lab/Earth ;;
esac

"${@:2}"সাবস্ট্রিং প্রসারণ বা অ্যারে সদস্য সম্প্রসারণের একটি ফর্ম যেখানে 2অফসেট is এটি দ্বিতীয় মান থেকে প্রসারণ শুরু করে। এটির সাথে আমাদের ব্যবহারের প্রয়োজন নাও হতে পারে shift

যোগ --প্রতিরোধ mvস্বীকৃতি ফাইলের নামের ড্যাশ (দিয়ে শুরু থেকে -) অবৈধ অপশন হিসাবে।


আপনি প্রতিটি ক্ষেত্রে ভাঙ্গা উচিত নয়?
আরচেমার

2
@ আর্চামার: না, কোনও পতনের মধ্য দিয়ে নেই (অন্যান্য অনেক ভাষার বিপরীতে)।
মাদুর

2
@ ম্যাট, যদি আপনি ( কেএসএইচ, বাশ, কেবল জেডএস) এর ;&পরিবর্তে ব্যবহার করেন তবে ফলস-হ'ল ;;। তবে breakতারপরেও পতনটি প্রতিরোধ করে না, breakকেবল লুপগুলি ভাঙার জন্য।
স্টাফেন চেজেলাস

ifএটি [কমান্ডের চেয়ে যুক্তি নয় ।
স্টাফেন চেজেলাস

1
সংশোধন: ডাবল উদ্ধৃতি কেবল বাম দিকে প্রয়োজন হয় না! [[ $foo == $bar ]]প্যাটার্ন মিলটি সম্পাদন করবে, তবে তা [[ $foo == "$bar" ]]করবে না।
nyuszika7h

7

এই ঘটছে কেন প্রশ্নে উত্তর দিতে, এই আচরণ [ওরফে testহয় POSIX মধ্যে নথিভুক্ত :

নিম্নলিখিত তালিকায়, $ 1, $ 2, $ 3, এবং $ 4 পরীক্ষার জন্য উপস্থাপনাগুলি উপস্থাপন করে:

[...]

1 টি যুক্তি:

$ 1 টি শূন্য না হলে সত্য (0) থেকে প্রস্থান করুন; অন্যথায়, মিথ্যা প্রস্থান করুন।

আপনি এটিকে 1 টি যুক্তি দিয়ে যাচ্ছেন 2=1, যা বাতিল নয়, এবং তাই testসাফল্যের সাথে প্রস্থান করে।

যেমন অন্যান্য পোস্টগুলি (এবং শেলচেক ) নির্দেশ করে, আপনি যদি সাম্যের জন্য তুলনা করতে চান, তবে পরিবর্তে আপনাকে 3 টি আর্গুমেন্ট পাস করতে হবে 2, =এবং 1


3
এক অর্থে এটিই একমাত্র উত্তর যা জিজ্ঞাসিত প্রশ্নের উত্তর দিয়েছে (বরং এক বা একাধিক রেসিপি দেওয়া যা ওপি অর্জন করতে চেয়েছিল তা করে), এবং শেল যথেষ্ট রহস্যময় হতে পারে যা জানে যে এটি যে কাজগুলি করে তা কেন কার্যকর তা কার্যকর? ।
dmckee --- প্রাক্তন-মডারেটর বিড়ালছানা

1

আমি কেবল একটি পোর্টেবল তবুও আরও ভাল বিকল্পের সুপারিশ করতে চাই । বাশ সর্বজনীন নয় (এবং যদি আপনার সর্বজনীন প্রয়োজন না হয় তবে আপনি কেন শেল স্ক্রিপ্ট লিখছেন?)

#! /bin/sh
action="$1"
shift
case "$action" in
    1) dest=Sun   ;;
    2) dest=Moon  ;;
    3) dest=Earth ;;
    *) echo "Unrecognized action code '$action' (must be 1, 2, or 3)" >&2; exit 1 ;;
esac
mv -- "$@" ~/lab/"$dest"

(Pedants উল্লেখ্য: হ্যাঁ, আমি কোট প্রায় জানেন $actionউপর case "$action" inলাইন অপ্রয়োজনীয়, কিন্তু আমি মনে করি এটা তাদের যাহাই হউক না কেন লাগাতে, যাতে ভবিষ্যতে পাঠকদের স্মরণ করতে হবে না উত্তম।)


1
"বাশ সর্বজনীন নয় (এবং যদি আপনার সার্বজনীন প্রয়োজন না হয় তবে আপনি শেল স্ক্রিপ্টটি কেন লিখছেন?)" - এর থেকে বোঝা যাচ্ছে যে ব্যাশ স্ক্রিপ্টিংয়ের কোনও ব্যবহারের ঘটনা নেই।
রুসলান

@ রাস্লান হ্যাঁ, এটি আমার বিবেচিত মতামত। পোর্টেবল /bin/shস্ক্রিপ্টগুলি লিখুন , আপনার যদি এটির প্রয়োজন হয়; অন্যথায়, স্ক্রিপ্টিং ভাষায় লিখুন যা শেলের চেয়ে কম ভয়ঙ্কর। মৌলিক পার্ল অনুবাদক আসলে আরো সম্ভবত এবং উত্তরাধিকার মালিকানা পরিবেশের মধ্যে উপস্থিত হতে কাটা-ডাউন চেয়ে ব্যাশ হয় এমবেডেড পরিবেশের।
zwol
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.