bash - বলত - পরাশক্তির দেশ কয়টি




একটি পরাশক্তি লাগে যে একটি বাশ উদীয়মান করা? (8)

আমি CShell ( csh ) ব্যবহার করতাম, যা আপনাকে একটি পরামিতি নেয় এমন একটি উপনাম তৈরি করতে দেয়। নোটেশন মত কিছু ছিল

alias junk="mv \\!* ~/.Trash"

বাশ, এই কাজ বলে মনে হচ্ছে না। ব্যাশের প্রচুর উপকারী বৈশিষ্ট্য রয়েছে বলে আমি মনে করি এইটি বাস্তবায়িত হয়েছে তবে আমি কীভাবে ভাবছি।


টিএল; ডিআরঃ পরিবর্তে এটি করুন

একটি কমান্ড মাঝখানে আর্গুমেন্ট করা একটি উপনাম চেয়ে একটি ফাংশন ব্যবহার করার জন্য এটি অনেক সহজ এবং আরও পঠনযোগ্য।

$ wrap_args() { echo "before [email protected] after"; }
$ wrap_args 1 2 3
before 1 2 3 after

আপনি যদি পড়েন তবে আপনি শেল আর্গুমেন্ট প্রক্রিয়াকরণ সম্পর্কে জানতে হবে এমন কিছু জিনিস শিখবেন। জ্ঞান বিপজ্জনক। অন্ধকার পার্শ্ব চিরতরে আপনার ভাগ্য নিয়ন্ত্রণ আগে, আপনি চান ফলাফল পেতে।

শোধন

bash aliases আর্গুমেন্ট গ্রহণ না , কিন্তু শেষ পর্যন্ত :

$ alias speak=echo
$ speak hello world
hello world

alias মাধ্যমে কমান্ড মধ্যম মধ্যে আর্গুমেন্ট নির্বাণ সত্যিই সম্ভব কিন্তু কুৎসিত পায়।

এই বাড়িতে চেষ্টা করবেন না, kiddies!

আপনি সীমাবদ্ধতা সীমাবদ্ধতা পছন্দ এবং অন্যদের কি অসম্ভব বলে কাজ করছেন, এখানে রেসিপি। শুধু আপনার চুল ঝাপসা হয়ে যায় এবং আপনার মুখ শেষ পর্যন্ত পাগল পাগল-বিজ্ঞানী-শৈলী ঢেকে যদি আমাকে দোষারোপ করবেন না।

কার্যকারিতাটি আর্গুমেন্টগুলিকে পাস করা হয় যা কেবলমাত্র একটি রেপারের শেষেই গ্রহণ করে যা তাদের মাঝখানে সন্নিবেশ করে এবং তারপর আপনার কমান্ডটি চালায়।

সমাধান 1

যদি আপনি প্রতি সেকেন্ডে একটি ফাংশন ব্যবহার করে সত্যিই হন তবে আপনি এটি ব্যবহার করতে পারেন:

$ alias wrap_args='f(){ echo before "[email protected]" after;  unset -f f; }; f'
$ wrap_args x y z
before x y z after

যদি আপনি শুধুমাত্র প্রথম যুক্তিটি চান তবে আপনি $1 দিয়ে [email protected] প্রতিস্থাপন করতে পারেন।

ব্যাখ্যা 1

এটি একটি অস্থায়ী ফাংশন f তৈরি করে, যা আর্গুমেন্টগুলি পাস করে (মনে রাখবেন যে f খুব শেষে বলা হয়)। unset -f ফাংশন সংজ্ঞাটি মুছে দেয় কারণ ওরফে মৃত্যুদন্ড কার্যকর করা হয় তবে এটি পরবর্তীকালে প্রায় ঝুলতে থাকে না।

সমাধান 2

আপনি একটি subshell ব্যবহার করতে পারেন:

$ alias wrap_args='sh -c '\''echo before "[email protected]" after'\'' _'

ব্যাখ্যা 2

উপনামটি একটি কমান্ড তৈরি করে:

sh -c 'echo before "[email protected]" after' _

মন্তব্যসমূহ:

  • স্থানধারক _ প্রয়োজন, কিন্তু এটি কিছু হতে পারে। এটি sh এর $0 সেট হয়ে যায় এবং ব্যবহারকারীর প্রদত্ত আর্গুমেন্টগুলির প্রথমটি খেয়ে যায় না। প্রদর্শন:

    sh -c 'echo Consumed: "$0" Printing: "[email protected]"' alcohol drunken babble
    Consumed: alcohol Printing: drunken babble
  • একক-কোট ভিতরে একক উদ্ধৃতি প্রয়োজন হয়। এখানে ডাবল উদ্ধৃতি দিয়ে কাজ না করে একটি উদাহরণ:

    $ sh -c "echo Consumed: $0 Printing: [email protected]" alcohol drunken babble
    Consumed: -bash Printing:

    এখানে ইন্টারেক্টিভ শেলের $0 এবং [email protected] এর মানগুলি sh passed হওয়ার আগে ডবল উদ্ধৃত করা হয়। এখানে প্রমাণ:

    echo "Consumed: $0 Printing: [email protected]"
    Consumed: -bash Printing:

    একক উদ্ধৃতিগুলি নিশ্চিত করে যে এই ভেরিয়েবলগুলি ইন্টারেক্টিভ শেল দ্বারা ব্যাখ্যা করা হয় না এবং sh -c প্রেরণ করা হয়।

    আপনি দ্বিগুণ উদ্ধৃতি এবং \[email protected] ব্যবহার করতে পারেন, তবে আপনার অভ্যাসগুলি উদ্ধৃত করার জন্য সর্বোত্তম অনুশীলন (যেহেতু তাদের স্পেস থাকতে পারে) এবং \"\[email protected]\" এমনকি উচ্ছৃঙ্খল দেখায় তবে এটি আপনাকে একটি অবাঞ্ছিত প্রতিযোগিতা জিতে সহায়তা করতে পারে যেখানে চুল ঝলসানো চুল এন্ট্রি জন্য একটি পূর্বশর্ত।


Bash alias সরাসরি পরামিতি গ্রহণ করে না। আপনাকে একটি ফাংশন এবং উপনাম তৈরি করতে হবে।

alias পরামিতি গ্রহণ করে না কিন্তু একটি ফাংশন শুধু একটি উপনাম মত বলা যেতে পারে। উদাহরণ স্বরূপ:

myfunction() {
    #do things with parameters like $1 such as
    mv "$1" "$1.bak"
    cp "$2" "$1"
}


myfunction old.conf new.conf #calls `myfunction`

যাইহোক, আপনার .bashrc সংজ্ঞায়িত বাশ ফাংশন এবং অন্যান্য ফাইল আপনার শেলের মধ্যে কমান্ড হিসাবে উপলব্ধ। সুতরাং উদাহরণস্বরূপ আপনি এই মত পূর্ববর্তী ফাংশন কল করতে পারেন

$ myfunction original.conf my.conf

উপরে উত্তরটি সংশোধন করা, আপনি এলিয়াসের জন্য যেমন 1 শব্দের সিনট্যাক্স পেতে পারেন, এটি একটি শেল বা .bashrc ফাইলগুলিতে অ্যাড-হক সংজ্ঞাগুলির জন্য আরও সুবিধাজনক:

bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }

bash$ myfunction original.conf my.conf

বন্ধ ডান বন্ধনী আগে আধা কোলন ভুলবেন না। একইভাবে, প্রকৃত প্রশ্নের জন্য:

csh% alias junk="mv \\!* ~/.Trash"

bash$ junk() { mv "[email protected]" ~/.Trash/; }

বা:

bash$ junk() { for item in "[email protected]" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }

একটি বিকল্প সমাধান marker ব্যবহার করা, যা আমি সম্প্রতি তৈরি করেছি এমন একটি টুল যা আপনাকে টেম্পলেটগুলির "বুকমার্ক" করার অনুমতি দেয় এবং কমান্ড স্থানধারকগুলিতে সহজে কার্সার রাখে:

আমি বেশিরভাগ সময় খুঁজে পেয়েছি যে, আমি শেল ফাংশন ব্যবহার করছি তাই আমাকে কমান্ড লাইনে বারবার ব্যবহৃত কমান্ডগুলি বারবার লিখতে হবে না। এই ব্যবহারের ক্ষেত্রে ফাংশন ব্যবহার করার সমস্যাটি আমার কমান্ড শব্দভাণ্ডারের নতুন শর্ত যোগ করে এবং বাস্তব ক্রমকে কী ফাংশন পরামিতি উল্লেখ করে তা মনে রাখা। মার্কার লক্ষ্য যে মানসিক বোঝা নিষ্কাশন করা হয়।


পরামিতি গ্রহণ করার জন্য, আপনি ফাংশন ব্যবহার করা উচিত!

যাইহোক, @ ওরিয়াস কার্যকর করার পরিবর্তে উদীয়মান তৈরি করার সময় $ @ ব্যাখ্যা করা হয় এবং $ এর বাইরে চলে গেলেও এটি কাজ করে না। আমি কিভাবে এই সমস্যা সমাধান করবেন?

আপনি এই সমস্যা পরিত্রাণ পেতে একটি উদ্যান পরিবর্তে শেল ফাংশন ব্যবহার করতে হবে। নিম্নরূপ আপনি foo সংজ্ঞায়িত করতে পারেন:

function foo() { /path/to/command "[email protected]" ;}

অথবা

foo() { /path/to/command "[email protected]" ;}

অবশেষে, নিম্নলিখিত সিনট্যাক্স ব্যবহার করে আপনার foo () কে কল করুন:

foo arg1 arg2 argN

আপনি আপনার foo () থেকে ~/.zshrc বা ~/.zshrc ফাইলটি ~/.zshrc করুন।

আপনার ক্ষেত্রে, এই কাজ করবে

function trash() { mv [email protected] ~/.Trash; }

প্রশ্ন কেবল ভুল জিজ্ঞাসা করা হয়। আপনি পরামিতিগুলি গ্রহণ করে এমন একটি উপনাম তৈরি করবেন না কারণ alias ইতিমধ্যে বিদ্যমান এমন কিছুর জন্য দ্বিতীয় নাম যোগ করে। ওপেন ফাংশনটি function কমান্ডটি নতুন ফাংশন তৈরি করতে চায়। ফাংশনটি ইতিমধ্যে একটি নাম আছে হিসাবে আপনি ফাংশন উদ্বায়ী করার প্রয়োজন নেই।

আমি মনে করি আপনি এই মত কিছু চাই:

function trash() { mv "[email protected]" ~/.Trash; }

এটাই! আপনি $ 1, $ 2, $ 3, ইত্যাদি প্যারামিটার ব্যবহার করতে পারেন অথবা কেবল তাদের $ @


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

সম্প্রতি আমাকে এই সমস্যার সমাধান করার জন্য বাধ্য করা হয়েছে যে আমি ভেরিয়েবল এবং ফাংশনগুলির সংজ্ঞা মুদ্রণ করার জন্য কিছু সংক্ষিপ্ত আদেশ তৈরি করতে চেয়েছিলাম। তাই আমি যে উদ্দেশ্যে কিছু ফাংশন লিখেছেন। যাইহোক, কিছু ভেরিয়েবল আছে যা কোন ফাংশন কল দ্বারা পরিবর্তিত (বা হতে পারে)। তাদের মধ্যে রয়েছে:

FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV

পরিবর্তনশীল Defns মুদ্রণ করতে আমি ব্যবহার করা হয়েছে মৌলিক কমান্ড (একটি ফাংশন)। সেট কমান্ড দ্বারা ফর্ম আউটপুট ছিল:

sv () { set | grep --color=never -- "^$1=.*"; }

উদাহরণ:

> V=voodoo
sv V
V=voodoo

সমস্যা: এটি বর্তমান প্রসঙ্গে যেমন উল্লিখিত ভেরিয়েবলগুলির সংজ্ঞাগুলি মুদ্রণ করবে না, যেমন, যদি কোন ইন্টারেক্টিভ শেল প্রম্পট (বা কোন ফাংশন কল না থাকে), FUNCNAME সংজ্ঞায়িত করা হয় না। কিন্তু আমার ফাংশন আমাকে ভুল তথ্য বলে:

> sv FUNCNAME
FUNCNAME=([0]="sv")

আমার সাথে আসা এক সমাধান এই বিষয়ে অন্যান্য পোস্টে অন্যদের দ্বারা উল্লেখ করা হয়েছে। পরিবর্তনশীল defns মুদ্রণ এই নির্দিষ্ট কমান্ডের জন্য, এবং যা শুধুমাত্র এক যুক্তি প্রয়োজন, আমি এই কাজ করেছেন:

alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'

যা সঠিক আউটপুট (কেউ না), এবং ফলাফল অবস্থা (মিথ্যা) দেয়:

> asv FUNCNAME
> echo $?
1

যাইহোক, আমি এখনও একটি সমাধান খুঁজে বের করতে বাধ্য মনে করি যা ইচ্ছাকৃতভাবে আর্গুমেন্টের সংখ্যাগুলির জন্য কাজ করে।

একটি বাশ আলী কমান্ডের ইচ্ছাকৃত আর্গুমেন্ট পাস করার একটি সাধারণ সমাধান:

# (I put this code in a file "alias-arg.sh"):

# cmd [arg1 ...] – an experimental command that optionally takes args,
# which are printed as "cmd(arg1 ...)"
#
# Also sets global variable "CMD_DONE" to "true".
#
cmd () { echo "cmd([email protected])"; declare -g CMD_DONE=true; }

# Now set up an alias "ac2" that passes to cmd two arguments placed
# after the alias, but passes them to cmd with their order reversed:
#
# ac2 cmd_arg2 cmd_arg1 – calls "cmd" as: "cmd cmd_arg1 cmd_arg2"
#
alias ac2='
    # Set up cmd to be execed after f() finishes:
    #
    trap '\''cmd "${CMD_ARGV[1]}" "${CMD_ARGV[0]}"'\'' SIGUSR1;
    #        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    #       (^This is the actually execed command^)
    #
    # f [arg0 arg1 ...] – acquires args and sets up trap to run cmd:
    f () {
        declare -ag CMD_ARGV=("[email protected]");  # array to give args to cmd
        kill -SIGUSR1 $$;             # this causes cmd to be run
        trap SIGUSR1;                 # unset the trap for SIGUSR1
        unset CMD_ARGV;               # clean up env...
        unset f;                      # incl. this function!
    };
    f'  # Finally, exec f, which will receive the args following "ac2".

উদাহরণ:

> . alias-arg.sh
> ac2 one two
cmd(two one)
>
> # Check to see that command run via trap affects this environment:
> asv CMD_DONE
CMD_DONE=true

এই সমাধান সম্পর্কে একটি চমৎকার জিনিস হল যে কমান্ডগুলিতে অবস্থানগত পরামিতি (আর্গুমেন্ট) হ্যান্ডেল করার জন্য ব্যবহৃত সমস্ত বিশেষ কৌশলগুলি ফাঁকা কমান্ড রচনা করার সময় কাজ করবে। শুধুমাত্র পার্থক্য যে অ্যারে সিনট্যাক্স ব্যবহার করা আবশ্যক।

যেমন,

আপনি যদি "$ @" চান তবে "$ {CMD_ARGV [@]}" ব্যবহার করুন।

আপনি যদি "$ #" চান তবে "$ {# CMD_ARGV [@]}" ব্যবহার করুন।

প্রভৃতি


যদি আপনি ফাংশনে সমস্ত প্যারামিটার প্রয়োগ করার জন্য একটি সাধারণ উপায় খুঁজছেন, কেবল এক বা দুই বা অন্য কোন হার্ডকোডেড পরিমাণ না করে, আপনি এভাবে এটি করতে পারেন:

#!/usr/bin/env bash

# you would want to `source` this file, maybe in your .bash_profile?
function runjar_fn(){
    java -jar myjar.jar "[email protected]";
}

alias runjar=runjar_fn;

তাই উপরে উল্লিখিত উদাহরণে, আমি যখন runjar রান করি তখন থেকে আমি সমস্ত পরামিতি পাস করি।

উদাহরণস্বরূপ, যদি আমি runjar hi there এটি আসলেই শেষ হয়ে যাবে java -jar myjar.jar hi there । আমি যদি runjar one two three java -jar myjar.jar one two three এটি java -jar myjar.jar one two three চালানো হবে। java -jar myjar.jar one two three

আমি এই [email protected] ভিত্তিক সমাধান পছন্দ করি কারণ এটি কোনও প্যারামিটারের সাথে কাজ করে।





alias