この質問をするのに私がLinuxを使うのに10年近くかかりました。それはすべて試行錯誤とランダムな深夜のインターネットサーフィンでした。
しかし、これには10年は必要ありません。 Linuxを使い始めたばかりの場合は、エイリアスを付けるタイミング、スクリプトを記述するタイミング、関数を記述するタイミングを知りたいですか?
エイリアスについては、引数を取らない非常に単純な操作にエイリアスを使用しています。
alias houston='cd /home/username/.scripts/'
それは明らかなようです。しかし、これを行う人もいます:
alias command="bash bashscriptname"
(そして、それを.bashrc
ファイルに追加します)
それをする正当な理由はありますか?一生懸命頑張っていますが、やりたいと思うような状況は本当に考えられません。そのため、違いが生じるEdgeケースがある場合は、以下に回答してください。
それは私がPATHに何かを入れてそれをchmod +x
する場所だからです。これは、長年のLinuxの試行錯誤の後に生まれたもう1つのことです。
次のトピックに進みます。たとえば、ホームディレクトリの隠しフォルダ(.scripts/
)を.bashrc
(PATH=$PATH:/home/username/.scripts/
)に行を追加するだけでPATHに追加したので、そこで実行可能なものはすべて自動的にオートコンプリートされます。
私がする必要がある場合。
本当に必要ないんですけどね? Pythonのように、シェル以外の言語でのみ使用します。
シェルの場合は、まったく同じ.bashrc
内に関数を記述できます。
funcname () {
somecommand -someARGS "$@"
}
私が述べたように、私は試行錯誤を通して多くのこれを発見しました。そして、私が本当に機能の美しさを見たのは、自分のコンピューターが死んだときだけでした。周囲の人々が使用していないときは、コンピューターを使わざるを得ませんでした。
スクリプトのディレクトリ全体をコンピュータ間で移動するのではなく、他のすべての.bashrcを自分のものに置き換えるだけでした。
しかし、私は何かを逃しましたか?
それでは、初心者のLinuxユーザーに、いつエイリアスを設定し、いつスクリプトを記述し、いつ関数を記述するかについて教えてください。
それが明らかでない場合、私はこれに答える人々が3つすべてのオプションを利用すると想定しています。エイリアスのみを使用する場合、またはスクリプトのみを使用する場合、または関数のみを使用する場合--またはエイリアスとスクリプトのみ、またはエイリアスと関数のみ、またはスクリプトと関数のみを使用する場合 —この質問は、あなたを対象としたものではありません。
エイリアスは、(一般に)コマンドのデフォルトオプションを変更する以上のことを効果的に行うべきではありません。コマンド名の単なるテキスト置換にすぎません。引数では何もできませんが、実際に実行するコマンドに渡します。したがって、単一のコマンドの前に引数を追加するだけでよい場合は、エイリアスが機能します。一般的な例は
# Make ls output in color by default.
alias ls="ls --color=auto"
# make mv ask before overwriting a file by default
alias mv="mv -i"
エイリアスよりも複雑なことをする必要があるが、それだけでは役に立たない場合は、関数を使用する必要があります。たとえば、パイプラインにあるかどうかに応じてgrep
のデフォルトの動作を変更することについて質問した質問に この回答 を入力します。
grep() {
if [[ -t 1 ]]; then
command grep -n "$@"
else
command grep "$@"
fi
}
エイリアスには複雑すぎるため(条件に基づいて異なるデフォルトを必要とする)、関数の完全な例ですが、非対話型スクリプトでは必要ありません。
関数が多すぎたり、関数が大きすぎたりする場合は、それらを隠しディレクトリの個別のファイルに入れ、~/.bashrc
:
if [ -d ~/.bash_functions ]; then
for file in ~/.bash_functions/*; do
. "$file"
done
fi
スクリプトはそれ自体で立つ必要があります。それは、再利用できる、または複数の目的で使用できるものとしての価値があるはずです。
他の回答は、個人的な好みに基づいたいくつかの柔らかい一般的なガイドラインを提供しますが、スクリプト、関数、またはエイリアスの間で決定するときに考慮する必要がある多くの適切なfactsを無視します。
$PATH
_検索で見つかった場合、多くのシェルはパス名のハッシュをメモリに保存して、将来の_$PATH
_ルックアップの時間を節約しますが、これはスクリプトのメモリフットプリントの範囲です。使用されていません。スクリプトは、関数やエイリアスよりも多くの方法で呼び出すことができます。これらは、_sh script
_などのインタープリターへの引数として渡すか、実行可能ファイルとして直接呼び出すことができます。その場合、Shebang行のインタープリター(例:_#!/bin/sh
_)を呼び出して実行します。どちらの場合も、スクリプトは、シェルの環境とは別の独自の環境を持つ独立したインタープリタープロセスによって実行されます。実際、インタプリタシェルは、呼び出し元のシェルと一致する必要さえありません。この方法で呼び出されたスクリプトは、通常の実行可能ファイルのように動作するように見えるため、任意のプログラムで使用できます。
最後に、現在のシェルで_.
_を使用して、または一部のシェルではsource
を使用して、スクリプトを読み取って実行できます。この場合、スクリプトは常にメモリに保持されるのではなく、オンデマンドで読み取られる関数のように動作します。
上記のことから、何かをスクリプトにするか、関数またはエイリアスにするかについて、いくつかの一般的なガイドラインを考え出すことができます。
シェル以外の他のプログラムで使用できるようにする必要がありますか?使用する場合は、スクリプトにする必要があります。
インタラクティブシェルからのみ利用できるようにしますか?外部コマンド/スクリプトに影響を与えずにインタラクティブに実行する場合、多くのコマンドのデフォルトの動作を変更するのが一般的です。この場合、シェルの「インタラクティブモードのみ」のrcファイルに設定されたエイリアス/関数を使用します(bash
の場合、これは_.bashrc
_です)。
シェルの環境を変更する必要がありますか?関数/エイリアスまたはソーススクリプトの両方を選択できます。
これは頻繁に使用するものですか?おそらくそれをメモリに保持する方が効率的であるため、可能であれば関数/エイリアスにします。
逆に、めったに使用しないものですか?その場合、不要なときにメモリを占有する意味がないので、スクリプトにします。
functions関数とエイリアスにはいくつかの重要な違いがありますが、関数はエイリアスと同じように実行できるため、グループ化されています。エイリアスはローカル変数を持つことも、引数を処理することもできません。また、エイリアスは、1行より長いものには不便です。
²Unixシステムで実行中のすべてのプロセスにはenvironmentがあり、_variable=value
_のペアで構成されています。これには、デフォルトロケールのLANG
やPATH
は、実行可能な検索パスを指定します。
一人一人の好み次第だと思います。私にとってロジックは次のようになります:
動作するを実行することを制限するものは何もありません。
少なくとも部分的には個人的な好みの問題です。一方、いくつかの明確な機能上の違いがあります。
シェルスクリプトを見て、ここ数年私はエイリアスの作成をやや止めました(エイリアスはすべて時間の経過とともに関数に成長する傾向があるため)、bash以外の環境からも利用できるようにする必要がある場合にのみスクリプトを実行します。
PS:alias command="bash bashscriptname"
については、実際にこれを行う理由はありません。 bashscriptname
が$ PATHにない場合でも、単純なalias c=/path/to/script
で十分です。
エイリアスと関数に関するいくつかの追加のポイントは次のとおりです。
例えば:
alias f='echo Alias'; f # prints "Alias"
function f { echo 'Function'; }; f # prints "Alias"
unalias f; f # prints "Function"
ご覧のとおり、エイリアスと関数には別々の名前空間があります。詳細はdeclare -A -p BASH_ALIASES
とdeclare -f f
を使用して見つけることができ、それらの定義が出力されます(どちらもメモリに格納されます)。
エイリアスの制限を示す例:
alias a='echo Alias'
a # OK: prints "Alias"
eval a; # OK: prints "Alias"
( alias a="Nested"; a ); # prints "Alias" (not "Nested")
( unalias a; a ); # prints "Alias"
bash -c "alias aa='Another Alias'; aa" # ERROR: bash: aa: command not found
ご覧のとおり、関数とは異なり、エイリアスはネストできません。また、その使用はインタラクティブセッションに限定されます。
最後に、次のように、関数を宣言してすぐに呼び出すことで、エイリアスで任意の計算を行うことができることに注意してください。
alias a_complex_thing='f() { do_stuff_in_function; } f'
これは、Gitエイリアスの場合にすでに広く使用されています。関数の宣言よりもそうすることの利点は、同じ名前の関数をたまたま宣言しているスクリプトをsourceing(または.
を使用)するだけではエイリアスを上書きできないことです。
スクリプトを作成するタイミング...
export
ed変数および/または関数のコピーは、valueによってスクリプトに渡されます。これらの変数への変更は、親スクリプトにされません。いつ関数を書くか...
エイリアスを書き込むタイミング...
~/.profile
や~/.bashrc
などの適切なログインスクリプト内にあります。ライブラリスクリプトなどのスクリプト内では、関数の名前が変更されているが下位互換性が必要な場合など、関数のエイリアスが必要になる場合があります。これは、すべての引数を新しい関数に渡す古い名前の単純な関数を作成することで実現できます...
# A bash in-script 'alias'
function oldFunction () { newFunction "$@"; }
私が信じていないもう1つのことが取り上げられました。関数は呼び出しプロセスのコンテキストで実行されますが、スクリプトは新しいシェルをフォークします。
これはパフォーマンスにとって重要かもしれません-fork()
とexec()
がないため、関数はより高速です。通常の状況では違いは些細なことですが、メモリ不足でページスラッシングのシステムをデバッグしている場合、大きな違いが生じる可能性があります。
また、現在のシェル環境を変更する場合は、関数を使用する必要があります。たとえば、関数は現在のシェルのコマンドルックアップ$PATH
を変更できますが、$PATH
のfork/execコピーを操作するため、スクリプトは変更できません。
スクリプトとエイリアス、およびスクリプトと関数は相互に排他的ではありません。スクリプトにエイリアスと関数を保存できます。
スクリプトは、永続化される単なるコードです。将来使用したい便利な関数やエイリアスはスクリプトに保存されています。ただし、多くの場合、スクリプトは複数の関数の集まりです。
エイリアスはパラメータ化されていませんなので、非常に制限されています。通常、いくつかのデフォルトパラメータを定義します。
A 関数はコードの個別の単位、数行のコードの明確に定義された概念であり、小さくて便利な部分に分割することはできません。直接または他の機能によって他のものが再利用できるもの。
非常に高速である必要がある場合は、エイリアスまたは関数にします。
使用するシェル以外でも使用できる場合は、スクリプトにします。1
引数を取る場合は、関数またはスクリプトにします。
特殊文字を含める必要がある場合は、エイリアスまたはスクリプトにしてください。2
Sudoで動作する必要がある場合は、エイリアスまたはスクリプトにします。3
ログアウトせずに簡単に変更したい場合は、スクリプトの方が簡単です。4
脚注
1 または、エイリアスにして~/.env
に入れ、export ENV="$HOME/.env"
を設定しますが、移植性を高めるには複雑です。
2 関数名は識別子である必要があるため、文字で始まる必要があり、文字、数字、アンダースコアのみを含めることができます。たとえば、エイリアスalias +='pushd +1'
があります。関数にすることはできません。
3 そして、エイリアスalias Sudo='Sudo '
を追加します。コマンドを最初の引数として取るstrace
、gdb
などの他のコマンドも同様です。
4 fpathも参照してください。もちろんsource ~/.bashrc
や同様のこともできますが、これには他の副作用がよくあります。
いくつかのメモを追加するだけです:
Sudo v /etc/rc.conf #where v runs vim in a new terminal window;
alias ls='ls --color=auto' #enable colored output;
# pressing key to open new terminal # waiting for a few seconds before Shell Prompt finally appears.
それ以外の場合は、可能な限り単純な形式を使用できます。つまり、最初にエイリアスを検討し、次に関数を検討し、次にスクリプトを検討します。
私の経験則は:
マルチユーザー(またはマルチsysamin)環境では、短い「exec something ...」ラッパーになってしまった場合でも、すべてにスクリプトを使用します。
確かに、技術的にはエイリアスや関数よりも速度が遅い/効率が悪いですが、それが問題になることはほとんどありません。パスに含まれていれば、スクリプトは常に機能します。
あなたの機能はcronから、Sudoやenvなどの削減または変更された環境から呼び出されたり、ユーザーが異なるシェルを使用している可能性があります。
パフォーマンスに影響を受けやすいものがある場合は、それを特別な場合として処理するか、さらに良い方法として、トリガーをより機能的なスクリプト言語で書き換えることを検討してください。
他のスクリプトでのみ使用される機能について話している場合は、標準のシェルを定義し、そのまま使用できる関数ライブラリスクリプトを作成することもできます。他のすべてのスクリプトに私を調達しました。
T
シェル以外のツールからコマンドを実行したい場合。
これにはvim(私にとって)が含まれます。フィルターやその他のプログラムをスクリプトとして記述した場合、:%!my-filter
などのようにして、エディターからプログラムを介してファイルをフィルター処理できます。
my-filter
が関数またはエイリアスの場合、それは不可能です。
私はこれが古い投稿であることを知っていますが、私はmostがエイリアスとスクリプトの組み合わせを使用する必要があり、私が選択した状況を指摘したいと思います関数を使用しないこと。
私は~/.bin/
にsetup
と呼ばれる次のスクリプトを持っています。1
要点はsetup <project-name>
を実行するだけの場合、これらの変数が定義されておらず、ディレクトリにアクセスできなかったことです。まったく。私が最良であるとわかった解決策は、このスクリプトをPATH
に追加し、alias setup=". ~/.bin/setup"
を~/.bashrc
に追加することです。
- スクリプト は
.bin/
の下にある my dotfiles repository で使用できます。- スクリプトについて:私はこのスクリプトに、私が詳細に定義したプロジェクトの名前である引数を与えます。その後、スクリプトは特定の
csv
ファイルに従って正しいディレクトリに移動することを知っています。それが定義する変数は、そのディレクトリのmakefileから取得されます。その後、スクリプトはls -l
およびgit status
を実行して、そこで何が起こっているかを示します。- そのスクリプトは、
.bin/
の下の私のdotfilesリポジトリでも利用できます。