1行のコマンドで定義して使用しようとしていますalias
。bash -c
注文する:
bash -c "eval $'df'"
うまくいきますが:
bash -c "eval $'alias df5=df\ndf5 -h'"
いいえ。alias
1行のコマンドで内部を定義して使用する理由と方法は何ですか?bash -c
~から先行は達成するのが難しい~の回答存在するeval
新しい行を含むコマンドを1行に書き込むには?:
「The is a C string」は、
$'...'
「に渡される前にリテラル改行にbash
拡張されます。\n
eval
したがって、私の理解はそれが'
にあるべきですeval
。バッシュマニュアル説明する:
文字を一重引用符(
'
)で囲むと、引用符内の各文字のリテラル値が保持されます。前にバックスラッシュがある場合でも、一重引用符の間に一重引用符を使用することはできません。
私の理解は"
ありますので、外部で使用する必要があるということですeval
。'
eval
コメント:
- バラより
eval
新しい行を含むコマンドを1行に書き込むには?\n
代わりに使用して説明してください。;
- この質問の動機は、実際のコマンド全体で別の操作(このコマンドの外観
docker run -it ubuntu:18.04 bash -c "eval $'alias pip=pip3\nsource blah.sh; exec bash"
)にaliasコマンドを使用することです。使用するblah.sh
場所 完全なpip
実際のコマンドですが、追加する必要がありますdocker run --interactive --tty ubuntu:18.04 bash -c "apt update; apt install -y git nano wget htop python3 python3-pip unzip; git clone https://github.com/KhalilMrini/LAL-Parser; cd LAL-Parser/; alias pip=pip3; source requirements.sh; apt-get install -y libhdf5-serial-dev; alias python=python3 ; source parse.sh; exec bash"
。このコマンドはDockerコンテナを起動し、いくつかの要件をインストールし、いくつかのPythonコードを実行します。eval
alias
- この命令は技術的な知識のない同僚のためのものです。それらが簡単に使用できるように、1行のコマンドのみを実行したいと思います。したがって、私はコマンドが
Dockerfile
機能するためにファイル(スクリプトなど)を要求したくありません。bash
次のコマンド:
bash -c " eval 'alias df5=df df5 -h' "
そしてコマンド
bash -c " alias df5=df df5 -h "
いいえ。間違い
bash: line 2: df5: command not found
。問題はalias
理由bash -c
を知らず、解決策があるかどうか疑問に思います。
答え1
修正された質問:
編集された質問について、「exec bashの後に対話型エイリアスは必要ありません」:
はい、bash -cは失敗します。
$ bash -c "
alias df5=df
df5 -h
"
bash: line 2: df5: command not found
ただし、エイリアス設定が失敗したためではありません。
$ bash -c "
alias df5=df
alias df5
"
alias df5=df
ただし、非対話型シェル(主にスクリプト)では、エイリアスはデフォルトで拡張されていないため、次のことを行う必要があります。
bash -c "
alias df5=df
shopt -s expand_aliases
df5 -h
"
これがエイリアスの代わりに関数を使用する重要な理由の1つです。
それが克服する必要があるすべての場合は、次を使用してください。
docker run --interactive --tty ubuntu:18.04 \
bash -c "
shopt -s expand_aliases;
apt update;
apt install -y git nano wget htop python3 python3-pip unzip;
git clone https://github.com/KhalilMrini/LAL-Parser;
cd LAL-Parser/;
alias pip=pip3;
source requirements.sh;
apt-get install -y libhdf5-serial-dev;
alias python=python3;
source parse.sh;
exec bash
"
1行のコードで機能する必要があります(改行が削除されました)。そうでない場合はコメントしてください。
編集前の質問:
以前の回答は次の問題を解決しました。 dockerが起動したインタラクティブシェルで最後にexec bash
。
新しい対話型シェルでのエイリアスの使用を妨げる実際の問題は、完全なコマンドです。
docker run --interactive --tty ubuntu:18.04 \
bash -c "
apt update;
apt install -y git nano wget htop python3 python3-pip unzip;
git clone https://github.com/KhalilMrini/LAL-Parser;
cd LAL-Parser/;
alias pip=pip3;
source requirements.sh;
apt-get install -y libhdf5-serial-dev;
alias python=python3;
source parse.sh;
exec bash
"
で終わりますexec bash
。これにより、実行されたスクリプトにエイリアスもなく、関数もない新しいクリーンなbashインスタンスが起動します。
考えられる解決策の1つは、exec bashを次に置き換えることです。
bash --rcfile <(echo '. ~/.bashrc; alias pip=pip3; alias python=python3')
これにより、ユーザー(dockerコマンドを実行している人)が、2つのエイリアスが定義されている対話型シェルに配置されます。
注:このアイデアは多くのパッケージをインストールする必要があるため、テストされていませんが機能します。
少なくとも以下を指します。本物コマンドに問題があります。
答え2
(他のシェルとは異なり)を使用すると、エイリアスはインタラクティブモードではない場合は拡張されないbash
ため、拡張されません。bash
これらのbash関連の偏見に加えて、エイリアス拡張のより重要な結果があります。 POSIX 標準の次のバージョンには、エイリアスに操作権限が付与されていない場合の問題を説明する説明が含まれます。
エイリアスはパーサの語彙アナライザ部分内で拡張され、エイリアスはシェルでエイリアスが知られており、関連するテキストフラグメントで語彙アナライザが呼び出される場合にのみ拡張されます。後ろにシェルはすでにこの別名を知っています。
したがって、エイリアス拡張をよりよく理解するには、シェルが解析をどのように実行するかを理解することも重要です。
シェルは通常、入力の行全体を解析し、結果を解釈し(別名コマンドが認識された場合)、次の行を解析し続けます。
これは、最良の場合、次のコード行でエイリアスが最初に拡張される理由を説明します。
Bourne Shell
などの従来のシェルでは、ksh
場合によってはまだ機能しません。その理由は、従来のシェルが結果の解釈を開始する前に一部の入力を1行ずつ分析するのではなく、ブロックごとに分析するためです。次の構造は、全体としてブロックに解析されます。
shell -c "cmd-arg"
サイズに関係なく の 全体 cmd-argeval
コマンドパラメータコマンドの置き換え
シェルの起動時に実行されるドットスクリプト
.
buitlin コマンドで実行されるスクリプト
この場合、コマンドがサブシェルで実行されると、定義されたエイリアスは適用されません。他の場合は、解析されたブロックが実行され、次の入力が解析された後にエイリアスが適用されます。
これを確認したい人は、NLFLG
Bourne Shellまたはkshソースを確認したいと思います。このフラグがパーサで使用される場合、改行文字は;
a を見るのと同じ方法で処理されます。
ご覧のとおり、スクリプトでエイリアスを使用しないと強力な影響を与える可能性があります。