Ash # বাশ মানে কি?


26

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

echo "hello world"
echo ${1}

এবং যখন আমি এই স্ক্রিপ্টটি ব্যবহার করে চালাচ্ছি:

./instance solfish

আমি এই আউটপুট পেতে:

hello world
solfish

তবে আমি যখন দৌড়ব:

echo $# 

এটি "0" বলে। কেন? আমি বুঝতে পারছি না $#মানে কি ।

দয়া করে এটি ব্যাখ্যা করুন।


10
আপনি দৌড়ান কেন $#? তুমি কি অর্জন করতে চাও? আপনি এই আদেশ কোথায় পেলেন? এটি মোটেই প্রাসঙ্গিক নয়।
পাইলট 6

7
@ পাইলট this এই ক্ষেত্রে তিনি একটি পরিবর্তনশীলটির অর্থ জিজ্ঞাসা করেন, এটি কেস সুনির্দিষ্ট নয় তাই অপটিকে কেন এই তথ্য দেওয়ার প্রয়োজন হবে?
এডিডিবি

21
@ সল্ফিশ পাইলট আপনি কী প্রত্যাশা করেছিলেন তা বোঝার চেষ্টা করছে। আপনি বলেছিলেন যে আপনি দৌড়ে echo $#এসেছেন এবং এটি ফিরে এসেছে 0যা স্বাভাবিক। আপনি এতে অবাক হয়েছিলেন, তবে আপনি কী আশা করেছিলেন বা কেন আপনি অবাক হয়েছিলেন তা আপনি ব্যাখ্যা করেন না। সুতরাং আপনি আমাদের কী আশা করছেন তা যদি ব্যাখ্যা করে তবে এটি আপনাকে আরও ভাল উত্তর দিতে সহায়তা করবে would আপনি কি ভেবেছিলেন যে এটি echo $#করবে। আপনি দৌড়ে ./instance solfishএবং ./instanceঅন্তর্ভুক্ত echo $#, যে প্রিন্ট হবে 1এবং 0
টেরডন


1
জাভাও আরগসি ব্যবহার করে না।
জেকরব

উত্তর:


66

$#bashএটিতে একটি বিশেষ পরিবর্তনশীল , এটি আর্গুমেন্টের সংখ্যা (অবস্থানগত পরামিতি) পর্যন্ত প্রসারিত হয় অর্থাৎ $1, $2 ...প্রশ্নে লিখিত স্ক্রিপ্টে বা শেলটি সরাসরি শেল যেমন পাস করার ক্ষেত্রে শেলটি পাস করে bash -c '...' ....

এটি argcসি এর মতোই is


সম্ভবত এটি পরিষ্কার করে দেবে:

$ bash -c 'echo $#'
0

$ bash -c 'echo $#' _ x
1

$ bash -c 'echo $#' _ x y
2

$ bash -c 'echo $#' _ x y z
3

মনে রাখবেন, bash -c0 ( $0; প্রযুক্তিগতভাবে, কমান্ডটি নিম্নলিখিতটি নিম্নলিখিতটি শুরু করার পরে আর্গুমেন্ট গ্রহণ করে ; প্রযুক্তিগতভাবে, এটি bashআপনাকে সেট করার সুযোগ মাত্র $0, কোনও যুক্তি সত্যিকারভাবে নয়), সুতরাং _এখানে কেবল স্থানধারক হিসাবে ব্যবহৃত হয়; প্রকৃত যুক্তি হ'ল x( $1), y( $2), এবং z( $3)।


একইভাবে, আপনার স্ক্রিপ্টে (ধরে নিচ্ছেন script.sh) যদি আপনার কাছে থাকে:

#!/usr/bin/env bash
echo "$#"

তারপরে আপনি যখন করবেন:

./script.sh foo bar

স্ক্রিপ্ট 2 আউটপুট হবে; একইভাবে,

./script.sh foo

আউটপুট 1 হবে।


1
আমি মনে করি এই উত্তরটি বিভ্রান্তিকর। $ # হল আর্গুমেন্টের অ্যারের সর্বাধিক সূচক। আপনি একটি আর্গুমেন্ট দিতে, তাহলে সেই $ 0 এ উপলব্ধ হবেন, এবং $ # মান 0. থাকবে আপনি দুই আর্গুমেন্ট দিতে, তাহলে তারা $ 0 এবং $ 1 এবং $ # হবেন মান 1. থাকবে
JakeRobb

1
তদ্ব্যতীত, আপনি যখন ব্যবহার করবেন তখন আপনি bash -cনির্বাহযোগ্য শেল স্ক্রিপ্টটি চালানোর চেয়ে আচরণের চেয়ে আলাদা হয় কারণ পরবর্তী ক্ষেত্রে সূচক 0 সহ যুক্তিটি এটির জন্য ব্যবহৃত শেল কমান্ড। এই হিসাবে, আমি মনে করি যে এই উত্তরটি ঠিক করার উপায় হ'ল এটি ব্যবহারের পরিবর্তে স্ক্রিপ্টগুলি ফাইল হিসাবে চালানোতে পরিবর্তন করা bash -c, যেহেতু প্রশ্নকারী এটি করছিল was
জ্যাকরব

1
@ জ্যাকরব নং, কোনও স্ক্রিপ্টের জন্য এটিই স্ক্রিপ্ট $0হবে; যুক্তি হবে $1, $2, $3...bash -cআচরণটি ভিন্ন কারণ এটি অ-ইন্টারেক্টিভ ব্যবহারের জন্য বোঝানো হয় এবং আদেশটি অনুসরণ করে যুক্তিগুলি শুরু করা উচিত $0, আমি এটি পরিষ্কারভাবে উল্লেখ করেছি যে আমি বিশ্বাস করি।
হিমাইল

5
@ জ্যাকরবঃ আপনি আমাকে ভুল শুনেছেন যদি আপনি একটি যুক্তি দেন তবে তা $ 0 এ উপলব্ধ হবে এবং $ # এর মান 0 থাকবে - এটি সাধারণ ভুল।
হিমাইল

2
যদি আপনি এমন একটি সম্পূর্ণ প্রোগ্রাম রাখেন যা এতে আর্গুমেন্ট দেখায় bash -c, তবে আপনাকে bash0 তম আর্গের ফিলার হিসাবে কিছু অর্থপূর্ণ নামটি দেওয়া উচিত । bash -c 'echo "$@"' foo barকেবল প্রিন্টগুলি bar, কারণ "$@"অন্তর্ভুক্ত নয় $0, সর্বদা হিসাবে একই। bash -c"$ 0 args এক করা" না, এটি নিছক আপনি সেট "$ 0" একই ভাবে যখন আপনি সঙ্গে একটি প্রোগ্রাম চলমান করতে পারবেন সিস্টেম কল বা 0th ARG অগ্রাহ্য কোন শেল উপায়। "আর্গুমেন্টগুলির মধ্যে একটি" হিসাবে বিবেচনা করা উচিত নয়। execve$0
পিটার

17

echo $# আপনার স্ক্রিপ্টের অবস্থানগত পরামিতিগুলির সংখ্যা আউটপুট করে।

আপনার কোনও নেই, সুতরাং এটি 0 আউটপুট করে।

echo $# পৃথক কমান্ড হিসাবে নয়, স্ক্রিপ্টের অভ্যন্তরে দরকারী।

আপনি যদি কিছু পরামিতি সহ স্ক্রিপ্ট চালান run

./instance par1 par2

echo $#স্ক্রিপ্টের মধ্যে রাখা 2 আউটপুট হবে।


6
ওপি-র উদাহরণের জন্য: আপনি যদি echo $#আপনার স্ক্রিপ্টে লাইনটি যুক্ত করেন এবং আবার চালানোর পরিবর্তে ./instance solfishআপনাকে একটি অতিরিক্ত আউটপুট লাইন পাওয়া উচিত 1যেহেতু আপনি 1 প্যারামিটার সরবরাহ করেছেন
derHugo

14

$#প্যারামিটারটি পাস হয়েছে তা নিশ্চিত করার জন্য ব্যাশ স্ক্রিপ্টগুলিতে সাধারণত ব্যবহৃত হয়। সাধারণত আপনি আপনার স্ক্রিপ্টের শুরুতে একটি প্যারামিটার পরীক্ষা করেন।

উদাহরণস্বরূপ, আমি আজ যে স্ক্রিপ্টে কাজ করছি তার একটি স্নিপেট এখানে:

if [[ $# -ne 1 ]]; then
    echo 'One argument required for file name, e.g. "Backup-2017-07-25"'
    echo '.tar will automatically be added as a file extension'
    exit 1
fi

$#প্রতিবেদনগুলি সংক্ষিপ্ত করতে কোনও স্ক্রিপ্টে পাস হওয়া প্যারামিটারের সংখ্যা। আপনার ক্ষেত্রে আপনি কোনও পরামিতি পাস করেন নি এবং রিপোর্টিত ফলাফল 0


#বাশের অন্যান্য ব্যবহার

#প্রায়ই ঘটনা ঘটার সংখ্যা বা একটি পরিবর্তনশীল এর দৈর্ঘ্য গণনা থেকে ব্যাশ ব্যবহার করা হয়।

একটি স্ট্রিংয়ের দৈর্ঘ্য সন্ধান করতে:

myvar="some string"; echo ${#myvar}

আয়: 11

অ্যারে উপাদানগুলির সংখ্যা সন্ধান করতে:

myArr=(A B C); echo ${#myArr[@]}

আয়: 3

প্রথম অ্যারে উপাদানটির দৈর্ঘ্য সন্ধান করতে:

myArr=(A B C); echo ${#myArr[0]}

রিটার্ন: 1( Aঅ্যারে শূন্য-ভিত্তিক সূচকগুলি / সাবস্ক্রিপ্ট ব্যবহার করায় 0 এর দৈর্ঘ্য প্রথম উপাদান)।


$# -ne 1? কেন $# -le 0বা সমমান নয়?
প্যাট্রিক ট্রেনটিন

@ পেট্রিকট্রেনটিন কারণ আমি চাই না যে তারা দুটি বা ততোধিক পরামিতি পাস করবে। ক্যাপ্টেন যেমন "রেড অক্টোবর" বলেছেন: "জাস্ট ওয়ান"।
WinEunuuchs2Unix

তারপরে: ত্রুটি বার্তায় "ঠিক একটি যুক্তি প্রয়োজন ..."
প্যাট্রিক ট্রেন্টিন

@ পেট্রিক্টর্টিন ত্রুটি বার্তাটি ব্যাখ্যা করে যে কীভাবে স্ক্রিপ্টটি এক যুক্তির ব্যবহারের উদাহরণ সহ ব্যবহার করা হয়। : উপরন্তু ব্যাকআপ স্ক্রিপ্ট cron.daily দ্বারা বলা হয় যা শুধুমাত্র কেউ প্রযুক্তিগতভাবে জ্ঞানী একবার কনফিগার করা askubuntu.com/questions/917562/...
WinEunuuchs2Unix

এটি কীভাবে প্রাসঙ্গিক তা আমি জানতাম না। যাইহোক, চিয়ার্স।
প্যাট্রিক ট্রেনটিন

10

$# আর্গুমেন্টের সংখ্যা, তবে মনে রাখবেন এটি কোনও ফাংশনে আলাদা হবে।

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

এই স্ক্রিপ্টটি সর্বদা মুদ্রণ করে 3, স্ক্রিপ্টে নিজেই কতগুলি আর্গুমেন্ট পাস হয়েছিল তা নির্বিশেষে, কারণ "$#"ফাংশনে ফাংশনে fপ্রেরিত আর্গুমেন্টের সংখ্যাটি প্রসারিত হয়:

#!/bin/sh

f() {
    echo "$#"
}

f a b c

এটি গুরুত্বপূর্ণ কারণ এটির মতো কোডটি আপনার প্রত্যাশা মতো কাজ করে না, আপনি যদি শেল ফাংশনগুলিতে অবস্থানগত পরামিতিগুলি কীভাবে কাজ করেন তার সাথে পরিচিত না হন:

#!/bin/sh

check_args() { # doesn't work!
    if [ "$#" -ne 2 ]; then
        printf '%s: error: need 2 arguments, got %d\n' "$0" "$#" >&2
        exit 1
    fi
}

# Maybe check some other things...
check_args
# Do other stuff...

ইন check_args, $#ফাংশন নিজেই পাস আর্গুমেন্ট সংখ্যা প্রসারিত, যা স্ক্রিপ্ট সর্বদা 0 হয়।

আপনি যদি শেল ফাংশনে এই জাতীয় কার্যকারিতা চান তবে আপনার পরিবর্তে এই জাতীয় কিছু লিখতে হবে:

#!/bin/sh

check_args() { # works -- the caller must pass the number of arguments received
    if [ "$1" -ne 2 ]; then
        printf '%s: error: need 2 arguments, got %d\n' "$0" "$1" >&2
        exit 1
    fi
}

# Maybe check some other things...
check_args "$#"

এটি কাজ করে কারণ ফাংশনের বাইরে$# প্রসারিত এবং এর অবস্থানগত পরামিতিগুলির একটি হিসাবে ফাংশনে চলে গেছে । ফাংশনের অভ্যন্তরে, প্রথম অবস্থানগত প্যারামিটারটি প্রসারিত হয় যা শেল ফাংশনে স্থান দেওয়া হয়েছিল, এর স্ক্রিপ্টের চেয়ে এটির অংশ নয়।$1

সুতরাং, মত $#, বিশেষ পরামিতি $1, $2ইত্যাদি, সেইসাথে $@এবং $*, এছাড়াও আর্গুমেন্ট একটি ফাংশন প্রেরণ করা, যখন তারা ফাংশনে প্রসারিত হয় অধিকারে থাকা। যাইহোক, ফাংশনটির নামে পরিবর্তন $0হয় না , এ কারণেই আমি এখনও এটি একটি মানের ত্রুটি বার্তা তৈরি করতে সক্ষম হয়েছি।

$ ./check-args-demo a b c
./check-args-demo: error: need 2 arguments, got 3

একইভাবে, আপনি যদি অন্যটির ভিতরে একটি ফাংশন সংজ্ঞায়িত করেন তবে আপনি অবস্থানগত পরামিতিগুলির সাথে কাজ করছেন যা অভ্যন্তরীণতম ফাংশনটিতে প্রসারিত হয়:

#!/bin/sh

outer() {
    inner() {
        printf 'inner() got %d arguments\n' "$#"
    }

    printf 'outer() got %d arguments\n' "$#"
    inner x y z
}

printf 'script got %d arguments\n' "$#"
outer p q

আমি এই স্ক্রিপ্টটি কল করেছি nestedএবং (চলার পরে chmod +x nested) আমি এটি চালিয়েছি:

$ ./nested a
script got 1 arguments
outer() got 2 arguments
inner() got 3 arguments

হ্যা আমি জানি. "1 টি আর্গুমেন্ট" একটি বহুবচন বাগ।

অবস্থানগত পরামিতিগুলিও পরিবর্তন করা যেতে পারে।

আপনি যদি কোনও স্ক্রিপ্ট লিখছেন, কোনও ফাংশনের বাইরের অবস্থানগত পরামিতিগুলি যদি আপনি না পরিবর্তন করেন তবে স্ক্রিপ্টে কমান্ড-লাইন আর্গুমেন্ট হবে ।

এগুলি পরিবর্তন করার একটি সাধারণ উপায় হ'ল shiftবিল্টিনের সাথে, যা প্রতিটি অবস্থানগত পরামিতিকে এক-এক করে বামে স্থানান্তরিত করে, প্রথমটি নামিয়ে $#1: হ্রাস করে:

#!/bin/sh

while [ "$#"  -ne 0 ]; do
    printf '%d argument(s) remaining.\nGot "%s".\n\n' "$#" "$1"
    shift
done
$ ./do-shift foo bar baz      # I named the script do-shift.
3 argument(s) remaining.
Got "foo".

2 argument(s) remaining.
Got "bar".

1 argument(s) remaining.
Got "baz".

সেগুলি setবিল্টিনের সাহায্যেও পরিবর্তন করা যেতে পারে :

#!/bin/sh

printf '%d args: %s\n' "$#" "$*"
set foo bar baz
printf '%d args: %s\n' "$#" "$*"
$ ./set-args a b c d e      # I named the script set-args.
5 args: a b c d e
3 args: foo bar baz

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