質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

14204閲覧

複数コマンドを実行するaliasでの引数の扱い

tsuemura

総合スコア663

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

2グッド

1クリップ

投稿2017/08/21 21:15

Bashのaliasに関する質問です。

例えば、mkdircdを一度に行いたいと思ったとき

alias mkcd='mkdir $1;cd $1'

とすると

$ mkcd sampledir mkdir: missing operand Try 'mkdir --help' for more information.

のように、引数sampledirが渡されません。
これを解決するには、

function mkcd() { mkdir $1; cd $1; } alias mkcd=mkcd

のように関数を作成すれば良い、ということは知っているのですが、
なぜ最初の例で動かないのか、仕組みが分からず気になっています。

「動かないものは動かないんだよ!!!」と言われてしまえばそうなのですが、
ご存じの方がいればお知恵を貸してください。

環境・バージョン情報

  • Ubuntu 14.04.3 LTS
  • GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
kuma3, shimitei👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

率直に言ってしまえば、「aliasは『入力された文字を置き換える』だけのもの」だからなのですが、ちょっと自分でも気になったので、もう少し調べてみました。

とりあえず、「コマンドは、manで調べろ」という事で。

まずは、「エイリアス」の項を見てみます。

エイリアス(alias) を使うと、 ある単語が単純なコマンドの先頭の単語として使われた場合に、 この文字列を別の単語に置換できます。

置換されるテキストに引き数を入れる仕組みはありません。 引き数が必要ならば、シェル関数を使わなければなりません (後述の 関数 を参照)

つまり、「alias mkcd='mkdir $1; cd $1'」として「mkcd sampledir」を実行した場合、「mkdir $1; cd $1 sampledir」とコマンドを入力された状態で実行されるということですね。

で、自分が気になったのは**「コマンドを入力された際の「$1」はどのような扱いになるの?」**という点です。

そこで、manの「位置パラメータ」の項を参照。

位置パラメータは、シェルが起動されたときにシェルの引き数が代入されますが、 組み込みコマンドの set を使って代入し直すこともできます。

例えば、

bash

1#!/bin/bash 2echo $1

という「hoge.sh」という名前のシェルスクリプトがあり、「./hoge.sh aaa」と実行したとすると、スクリプトは先頭に書かれたコマンドを実行するわけですから、実際は「/bin/bash hoge.sh aaa」が起動されます。
つまり、「起動されたシェル」とはその時に実行された「/bin/bash」であり、「$1」はその時に指定された引数、先の場合だと「aaa」になるわけです。

コマンドを入力した場合には、「起動されたシェル」とは、例えばubuntuの「端末」(gnome-terminal)であれば端末が起動された時に起動されたbashの事になり、「$1」はその時に実行されたbashの引数が代入されるわけでコマンド入力された引数が代入されるわけではない、という事になるかと思います。

…ちょっと説明が下手なんで後半わかりづらいと思いますが、とりあえず「man bash」を見ましょう(笑)

投稿2017/08/21 23:00

katsuko

総合スコア3469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tsuemura

2017/08/21 23:36

ありがとうございます。納得がいきました。 > 「mkdir $1; cd $1 sampledir」とコマンドを入力された状態で実行されるということですね。 という部分が分かっていなかったです。 alias hoge="mkdir $1" のようにすると動作するので不思議でしたが、これですっきりしました。
otn

2017/08/22 02:51 編集

> alias hoge="mkdir $1" 特に設定しない限り$1が空になるので、 alias hoge=mkdir と同じですね。 さらに二重引用符なので、alias定義時点で$1が置換されるし。
guest

0

alias の定義の実体部分はサブシェルではないので、$1 が評価されるのが
(mkcd 実行時ではなく)alias 実行時点だからだと理解しています。

function で定義すると、全体がサブシェルのような扱いになり、位置
パラメータが有効になるのかな、と。

投稿2017/08/21 22:26

hotta

総合スコア1613

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tsuemura

2017/08/21 23:38

ありがとうございます。参考になりました。
otn

2017/08/22 02:53

関数もサブシェルではなくて、$1 $2 $# などのバインドが置き換えられて(=一時的に意味が変わって)実行するだけです。
hotta

2017/08/22 02:56

バインドって言うんですね。言葉がわからないと検索するのにも困ります。ご指摘ありがとうございます。
otn

2017/08/22 02:59

一般に、代入ではないんだけど、名前と値が関連付いているような状態を指して、「バインドされている」と言う事が多いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問