web-dev-qa-db-ja.com

ソース/ dev / stdinが期待どおりに機能しない

source /dev/stdinがまったく使用できないことを確認するために役立つ簡単なテストから始めましょう。

# echo -ne 'echo a\necho b\n' | source /dev/stdin
a
b

今、私は実際の機能を調達したいと思います。

# echo -ne 'f() { echo a; }\n' | source /dev/stdin
# f
-bash: f: command not found

では、一時ファイルを試してみましょう。

# echo -ne 'f() { echo a; }\n' > tempf
# source tempf
# f
a

したがって、一時ファイルは機能します。しかし、それは私の場合非常に不便であり、パイプが同様に機能しないはずの正当な理由はわかりません。

# bash --version
GNU bash, version 4.2.53(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

完全を期すために、実際の使用例は、Gentooポーテージの制限を回避するために、ファイルのどの部分を含めるかを慎重に選択することです。

post_src_unpack() {
    if type epatch_user > /dev/null 2>&1; then
        epatch_user || die
    else
        awk \
            '/^# @FUNCTION: / { p = 0 } /^# @FUNCTION: epatch(_user)?$/ { p = 1; } p { print  }' \
            /usr/portage/eclass/eutils.eclass | source /dev/stdin || die
        epatch_user || die
        unset epatch
        unset epatch_user
    fi
}

コードの目的は、多数の関数を含むソースファイルから必要な関数epatchepatch_userを2つだけ抽出し、それらを現在のシェルで使用できるようにし、そのうちの1つを実行することです他の)、そしてそれらを削除します。最終的な目標は、eutilsを継承するebuildのみがepatch_userにアクセスできるというGentooの制限を回避することです。

5
Pavel Šimerda

プロセス置換 を使用できます

source /dev/stdin < <(echo -ne 'f() { echo a; }\n')

または

source <(echo -ne 'f() { echo a; }\n')

これはbash4.1.5で機能しますが、何らかの理由で3.2.48では機能しません。

3
Barmar

パイプライン の各部分は 分離されたプロセスまたは独自のサブシェル で実行されます。したがって、パイプラインが終了すると、現在のシェルは関数fについて何も知りません。

bashkshpdkshzshmksh、またはサポートするシェル Here-String ) 、あなたは使うことができます:

$ source /dev/stdin <<<'f() { echo a; }'
$ f
a

POSIXlyでは、 Here-Document および dot を使用する必要があります。

$ . /dev/stdin <<'EOF'
> f() { echo a; }
> EOF

$ f
a
4
cuonglm

パイプ内のコマンドは個別のプロセスであるため、/dev/stdinをソースとする関数定義は、パイプが完了するとすぐに失われます。そのため、パイプは一時ファイルの使用法とは異なる結果を示します。

あなたのユースケースでは、PM 2Ringが推奨する方法であるeval.

2
wurtel