Aচ্ছিক ইনপুট আর্গুমেন্ট গ্রহণ করে এমন কোনও বাশ স্ক্রিপ্ট কীভাবে লিখবেন?


471

আমি চাই আমার স্ক্রিপ্টটি একটি alচ্ছিক ইনপুট নিতে সক্ষম হবে,

যেমন বর্তমানে আমার লিপিটি

#!/bin/bash
somecommand foo

তবে আমি এটি বলতে চাই:

#!/bin/bash
somecommand  [ if $1 exists, $1, else, foo ]

3
বাশ বা পসিক্স? বাশের সাথে, আরও সম্ভাবনা রয়েছে
ব্যবহারকারীর 123444555621

@ পুম্বা 80 বাশ - আমি ট্যাগগুলি আপডেট করেছি।
আবে


উত্তর:


705

আপনি ডিফল্ট-মান সিনট্যাক্স ব্যবহার করতে পারেন:

somecommand ${1:-foo}

উপরের উইলটি , যেমন বাশ রেফারেন্স ম্যানুয়ালটিতে বর্ণিত হয়েছে - 3.5.3 শেল প্যারামিটার সম্প্রসারণ [জোর খনি]:

যদি প্যারামিটারটি সেট না করা বা শূন্য হয় তবে শব্দের প্রসারণটি প্রতিস্থাপিত হয়। অন্যথায়, প্যারামিটারের মান প্রতিস্থাপিত হয়।

যদি আপনি কেবলমাত্র প্যারামিটারটি সেট না করা অবস্থায় একটি ডিফল্ট মান পরিবর্তিত করতে চান (তবে এটি নাল হয় না তবে যেমন এটি খালি স্ট্রিং না হয়ে থাকে) তবে পরিবর্তে এই বাক্য গঠনটি ব্যবহার করুন:

somecommand ${1-foo}

আবার বাশ রেফারেন্স ম্যানুয়াল থেকে - 3.5.3 শেল প্যারামিটার সম্প্রসারণ :

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


52
উপরের কমান্ডের মধ্যে শব্দার্থক পার্থক্যটি দয়া করে নোট করুন, " আনসেট না fooহলে ফিরে যান বা একটি খালি স্ট্রিং " এবং , " আনসেট না হলে ফিরে আসুন"। $1${1-foo}foo$1
l0b0

12
আপনি ব্যাখ্যা করতে পারেন কেন এটি কাজ করে? বিশেষভাবে, ':' এবং '-' এর কার্য / উদ্দেশ্য কী?
jwien001

8
@ jwein001: উপরে জমা দেওয়া উত্তরে, পরিবর্তনশীল অপরিবর্তিত থাকলে একটি বিকল্প অপারেটর একটি ডিফল্ট মান প্রদান করতে ব্যবহৃত হয়। বিশেষত, যুক্তিটি হ'ল "যদি $ 1 বিদ্যমান থাকে এবং শূন্য না হয় তবে এর মানটি ফিরিয়ে দিন; অন্যথায়, foo ফেরান।" কোলন alচ্ছিক। যদি এটি বাদ দেওয়া হয় তবে পরিবর্তন "বিদ্যমান এবং নাল নয়" কেবলমাত্র "বিদ্যমান"। বিয়োগ চিহ্নটি 'foo' এর সমান $ 1 সেট না করেই foo ফেরত যেতে নির্দিষ্ট করে। সাবস্টিটিউশন অপারেটরগুলি এক্সপেনশন অপারেটরগুলির একটি সাবক্লাস। রবিনস এবং বিবের ক্লাসিক শেল স্ক্রিপ্টিং [ও'রেলি] ( শপ.ওরিলি
প্রোডাক্ট /

5
@ জুবলস বা আপনি যদি কোনও সাধারণ রেফারেন্সের জন্য পুরো বইটি কিনতে না চান ... tldp.org/LDP/abs/html/parameter-substुट
ওহাদ স্নাইডার

2
এই উত্তরটি আরও ভাল হতে পারে যদি এটি নির্দেশ করে যে কীভাবে ডিফল্টটিকে কোনও কমান্ড চালানোর ফলাফল হিসাবে দেখা যায়, যেমন @ হেজেন (যদিও সেই উত্তরটি কার্যকর নয়)।
সৌদিমান

309

আপনি যেমন ভেরিয়েবলের জন্য একটি ডিফল্ট মান সেট করতে পারেন:

somecommand.sh

#!/usr/bin/env bash

ARG1=${1:-foo}
ARG2=${2:-bar}
ARG3=${3:-1}
ARG4=${4:-$(date)}

echo "$ARG1"
echo "$ARG2"
echo "$ARG3"
echo "$ARG4"

এটি কীভাবে কাজ করে তার কয়েকটি উদাহরণ এখানে দেওয়া হল:

$ ./somecommand.sh
foo
bar
1
Thu Mar 29 10:03:20 ADT 2018

$ ./somecommand.sh ez
ez
bar
1
Thu Mar 29 10:03:40 ADT 2018

$ ./somecommand.sh able was i
able
was
i
Thu Mar 29 10:03:54 ADT 2018

$ ./somecommand.sh "able was i"
able was i
bar
1
Thu Mar 29 10:04:01 ADT 2018

$ ./somecommand.sh "able was i" super
able was i
super
1
Thu Mar 29 10:04:10 ADT 2018

$ ./somecommand.sh "" "super duper"
foo
super duper
1
Thu Mar 29 10:05:04 ADT 2018

$ ./somecommand.sh "" "super duper" hi you
foo
super duper
hi
you

2
আহ, ঠিক আছে. -আমাকে বিভ্রান্ত (এটা অস্বীকার করা হয়?)।
রাফি খ্যাচডৌরিয়ান

5
না - এটি কেবল অ্যাসাইনমেন্টটি করার মতো এক অদ্ভুত উপায়। এটিকে কিছুটা স্পষ্ট করতে আমি আরও কিছু উদাহরণ যুক্ত করব ... ধন্যবাদ!
ব্র্যাড পার্কস

44
if [ ! -z $1 ] 
then 
    : # $1 was given
else
    : # $1 was not given
fi

1
প্রযুক্তিগতভাবে, যদি আপনি একটি খালি স্ট্রিং '' পাস করেন তবে এটি প্যারামিটার হিসাবে গণনা করতে পারে, তবে আপনার চেকটি এটি মিস করবে।
সেক্ষেত্রে

18
-nহিসাবে একই ! -z
l0b0

আমি ব্যবহার করে বিভিন্ন ফলাফল পেয়েছি -nএবং ! -zতাই আমি বলব যে এখানে এটি হয় না।
এলিজার

কারণ আপনি ভেরিয়েবলটি উদ্ধৃত করতে ব্যর্থ হয়েছেন, [ -n $1 ] সর্বদা সত্য হবে । আপনি যদি ব্যাশ ব্যবহার [[ -n $1 ]]করেন তবে আপনার প্রত্যাশার সাথে আচরণ করবেন, অন্যথায় আপনাকে উদ্ধৃতি দিতে হবে[ -n "$1" ]
glenn jackman

21

আপনি যুক্তি সংখ্যা পরীক্ষা করতে পারেন $#

#!/bin/bash
if [ $# -ge 1 ]
then
    $1
else
    foo
fi

10

দয়া করে ভুলে যাবেন না, যদি এর ভেরিয়েবল $ 1 .. you n প্রতিস্থাপনটি ব্যবহার করার জন্য আপনার নিয়মিত পরিবর্তনশীলকে লিখতে হবে

#!/bin/bash
NOW=$1
echo  ${NOW:-$(date +"%Y-%m-%d")}

2
উপরের ব্র্যাডের উত্তর প্রমাণ করে যে আর্গুমেন্ট ভেরিয়েবলগুলি অন্তর্বর্তী ভারগুলি ছাড়াও প্রতিস্থাপন করা যেতে পারে।
ভাদজিম

2
নির্দিষ্ট মানের পরিবর্তে ডিফল্ট হিসাবে তারিখের মতো একটি কমান্ড ব্যবহার করার উপায় লক্ষ করার জন্য +1। এটিও সম্ভব:DAY=${1:-$(date +%F -d "yesterday")}
গ্যারেন এস

3

Multipleচ্ছিক একাধিক যুক্তির জন্য, lsকমান্ডের সাথে সাদৃশ্য করে যা এক বা একাধিক ফাইল নিতে পারে বা ডিফল্টরূপে বর্তমান ডিরেক্টরিতে সমস্ত কিছু তালিকাভুক্ত করে:

if [ $# -ge 1 ]
then
    files="$@"
else
    files=*
fi
for f in $files
do
    echo "found $f"
done

পথের ফাঁকা জায়গাগুলি সহ ফাইলগুলির জন্য সঠিকভাবে কাজ করে না, হায়। কীভাবে এখনও এই কাজটি করা যায় তা ভেবে দেখেননি।


2

এটি 1stচ্ছিক প্রথম আরগের জন্য ডিফল্ট মানটিকে মঞ্জুরি দেয় এবং একাধিক আরগ সংরক্ষণ করে।

 > cat mosh.sh
   set -- ${1:-xyz} ${@:2:$#} ; echo $*    
 > mosh.sh
   xyz
 > mosh.sh  1 2 3
   1 2 3 

1

dateআর্গুমেন্টের জন্য একটি স্থির মান বা কমান্ডের (যেমন ) বিকল্পের জন্য পরিবর্তনশীল বিকল্প ব্যবহার সম্ভব । উত্তরগুলি এখন পর্যন্ত স্থির মানগুলিতে ফোকাস করেছে, তবে এটিই আমি তারিখটিকে একটি alচ্ছিক যুক্তি হিসাবে ব্যবহার করেছি:

~$ sh co.sh
2017-01-05

~$ sh co.sh 2017-01-04
2017-01-04

~$ cat co.sh

DAY=${1:-$(date +%F -d "yesterday")}
echo $DAY
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.