Nexenta bashスクリプトは、/ usr / bin / sedの代わりに/ usr / sun / bin / sedを使用します


3

LinuxおよびSolaris(Nexenta)用のスクリプトを使用しています。

この行はLinuxでは機能しますが、solarisでは機能しません(ただし、シェルから実行すると機能します)。

cat "pg_hba.conf" | sed "0,/^local/{s/md5/trust/}"

エラーメッセージは次のとおりです。

sed: command garbled: 0,/^local/{s/md5/trust/}

いくつかの調査の後sed、スクリプトでbashが使用するものが異なることがわかりました。

シェルから: /usr/bin/sed

スクリプトから: /usr/sun/bin/sed

スクリプトを使用させたい/usr/bin/sed

私がやろうとしたこと:

  1. sedフルパスで呼び出します。同じ結果。それはまだ他を使用しているようsedです...
  2. 経由で呼び出そうとしましたbash -l。同じ結果。
  3. 別のコマンドを宣言しようとしました:代わりにS=/usr/lib/sed使用し$Sます。同じ結果。
  4. PATHをチェック-cmdとスクリプトの両方に含ま/usr/binれています。
  5. 二重引用符を単一に置き換えようとしました。同じ結果。
  6. -rフラグを指定してsedを実行してみました。出力は次のとおりです。

    # /usr/xpg4/bin/sed -r /usr/xpg4/bin/sed: illegal option -- r Usage: sed [-n] script [file...] sed [-n] [-e script]...[-f script_file]...[file...]

助けて??

「ローカル」で始まる最初の行で、「md5」の最初の一致を「信頼」に置き換える必要があります。そうでない場合でもできることはわかっていますが、sed問題はかゆみが多すぎることです!

編集:

私はこれが少し注文をすることを望みます...

  1. ログインシェルからのパス= /usr/local/ctera/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/ctera/apache-ant-1.8.2/bin
  2. スクリプトからのパス=
    /usr/sbin:/usr/bin:/usr/local/ctera/apache-ant-1.8.2/bin:/usr/local/ctera/apache-ant-1.8.2/bin
  3. PATH=$(command -p getconf PATH):$PATH呼び出されたときのスクリプトからのパス= /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin:/usr/bin:/usr/local/ctera/apache-ant-1.8.2/bin:/usr/local/ctera/apache-ant-1.8.2/bin
  4. truss -f sed ログインシェル呼び出しから /usr/bin/sed
  5. truss -f sed スクリプト呼び出しから /usr/sun/bin/sed
  6. truss -f /usr/bin/sedスクリプト呼び出しから/usr/sun/bin/sed!!!
  7. 設定後PATH=$(command -p getconf PATH):$PATH
    7.1をtruss -f sedスクリプトから呼び出す/usr/xpg4/bin/sed
    7.2をtruss -f /usr/bin/sedスクリプトの呼び出しから/usr/sun/bin/sed

詳細:

コマンド出力:(シェルプロンプトとスクリプト内の両方から実行)

  1. truss -ft execve /usr/bin/sed q
    シェルコマンドとして:
    8604: execve("/usr/bin/sed", 0x08047D20, 0x08047D2C) argc = 2
    スクリプトから:
    8545: execve("/usr/sun/bin/sed", 0x08047768, 0x08047774) argc = 2

  2. file /usr/bin/sed
    シェルコマンドとして:
    /usr/bin/sed: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped
    スクリプトから:
    file: /usr/bin/sed zero size or zero entry ELF section - ELF capabilities ignored file: /usr/bin/sed: can't read ELF header /usr/bin/sed: data

  3. ls -l /usr/bin/sed
    シェルコマンドとして:
    -rwxr-xr-x 1 root root 96440 May 31 2008 /usr/bin/sed
    スクリプトから:
    -rwxr-xr-x 1 root root 96440 May 31 2008 /usr/bin/sed

  4. ls -ld $(type -pa sed)
    シェルコマンドとして:
    -rwxr-xr-x 1 root root 96440 May 31 2008 /bin/sed -rwxr-xr-x 1 root root 96440 May 31 2008 /usr/bin/sed
    スクリプトから:
    -rwxr-xr-x 1 root root 96440 May 31 2008 /usr/bin/sed

  5. md5sum $(type -pa sed)
    シェルコマンドとして:
    385361c5111226c8eac8e25b53fed29c /bin/sed 385361c5111226c8eac8e25b53fed29c /usr/bin/sed
    スクリプトから:
    385361c5111226c8eac8e25b53fed29c /usr/bin/sed

    • スクリプトはJAVAコードによって呼び出されます。

    • uname -a
      SunOS cteraportal 5.11 NexentaOS_134f i86pc i386 i86pc Solaris

    • これsedにより、マシンのバージョンに関する情報が追加される場合があります

      ~# ll `find / -name sed`  
      -rwxr-xr-x 1 root root 96440 May 31  2008 /usr/bin/sed  
      -r-xr-xr-x 1 root bin  35656 Sep  7  2010 /usr/sun/bin/sed  
      -r-xr-xr-x 1 root bin  32104 Sep  7  2010 /usr/ucb/sed  
      -r-xr-xr-x 1 root bin  35636 Sep  7  2010 /usr/xpg4/bin/sed  
      
      /usr/share/doc/sed:  
      total 113  
      -rw-r--r-- 1 root root   168 Jun 21  2005 AUTHORS.gz  
      -rw-r--r-- 1 root root  2507 Jun 21  2005 BUGS.gz  
      -rw-r--r-- 1 root root  6584 Feb  3  2006 NEWS.gz  
      -rw-r--r-- 1 root root   285 Jun 21  2005 README.gz  
      -rw-r--r-- 1 root root  1071 Jan 12  2006 THANKS.gz  
      -rw-r--r-- 1 root root  4806 May 31  2008 changelog.Debian.gz  
      -rw-r--r-- 1 root root 32312 Feb  3  2006 changelog.gz  
      -rw-r--r-- 1 root root   796 May 31  2008 copyright  
      drwxr-xr-x 2 root root     3 May 30  2011 examples  
      drwxr-xr-x 2 root root     3 May 30  2011 sed-4.1.5  
      -rw-r--r-- 1 root root 56538 May 31  2008 sedfaq.txt.gz  
      

あなたのsedコマンドでは、構文的に正しくない可能性があります。通常、呼び出すsedと、フラグが続きます。例:sed 's/cat/dog/g'
ryekayo 14

しかし、cmd
csny 14

二重引用符を単一引用符に置き換えてみてください。私は構文がこれと関係があるかもしれないと推測していますが、100%ではありません。
リエカヨ14

それだけでなく:)同じ結果を試みたが...私が含まれ、この提案で私のポストを編集します
csny

私は何をすることに0,なっていますか?
リエカヨ14

回答:


2

わかった。それは今理にかなっています。

動作はNexenta固有であり、http://lwn.net/Articles/334756/で説明されています

GNUではなくGNU

Nexentaのデフォルトの動作は、内に設置されているGNUユーティリティ、好むことです/usr/binし、/usr/sbinなどを。これらのユーティリティの日のバージョンはに設置されている/usr/sun/bin/usr/sun/sbin。Nexentaは、GNUとSUNパーソナリティを切り替えるためのトリックを使用します。環境変数SUN_PERSONALITYが1に設定されている場合、ユーザーが絶対パスで明示的にコマンドを実行した場合でも、検索パス/usr/sun/bin/usr/sun/sbin優先順位を取得します/usr/bin/sed。これにより、Solarisベースのスクリプトが変更なしでNexentaで動作することが保証されます。Nexentaは、SVR4パッケージコマンドでもこの機能を使用しています。これらを使用して、ネイティブのSolarisパッケージをSVR4形式でインストールし、alienを呼び出してその場でパッケージをDebianパッケージに変換できます。

これはlibcのどこかで行われます。

そう、

$ sed --version
GNU sed version 4.1.5
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,
to the extent permitted by law.
$ SUN_PERSONALITY=1 sed --version
sed: illegal option -- version

したがって、Javaから起動したスクリプトには、SUN_PERSONALITYが設定されている必要があります。

GNUツールが必要な場合は、スクリプトで設定を解除できます。


2
POSIXLY_CORRECT--posixスイッチ、そしてsedそれらの存在下でのGNU の振る舞いについても同様の疑いがありましたが、テストで乾いてしまい、あきらめました。それでも-私はこのコマンドについて学びました:sed v ...何もしません...しかしsed、GNU sed拡張がサポートされていない場合は失敗します...他sedのsがそれを実装していないためです。...必要なバージョンを指定できます...など4.0.5。デフォルトは4.0... v 場合でも、すべてのGNU拡張を可能POSIXLY_CORRECTな環境に設定されています。
mikeserv 14

unset SUN_PERSONALITY動作しますが、他のもののSUN機能に依存しているように見えるため、他のものを台無しにします。だから私unsetexportそれを1に戻すと、すべてが機能します。ありがとう!
csny 14

@csny、スクリプトではPOSIX構文を使用します。Sun(少なくともafter PATH=$(getconf PATH):$PATH)とGnuは、ほとんどがPOSIX互換です。
ステファンシャゼル14

1
これを読んでいる人に:それSUN_PERSONALITYはネクセンタの発明であり、Solarisに存在するものではないことを指摘したかっただけです。
ペテル14

@ nolan6000、私はそれが指摘されるべきであることに同意します。私はそれをより明確にするために私の答えを更新し、質問sのタイトル/ Solarisの/ Nexenta /変更しました
ステファンChazelas

2

とにかく、

sed "0,/^local/{s/md5/trust/}"

GNU固有(0アドレスと;以前の欠落})であり、他のsed実装では動作しません(SolarisはsedデフォルトでGNUに同梱されていません)。

移植可能/標準:

sed '/^local/,$!s/md5/trust/'

で始まる最初の行まで(ただし含まれない)の行でのみ置換しlocalます。または:

awk 'NR == 1, /^local/ {gsub(/md5/,"trust")}; {print}'

(Solarisでは、必要になる場合がありますcommand -p awk)。

一致する最初の行で置換が必要な場合/^local/

awk '/^local/ && ! seen {gsub(/md5/, "trust"); seen = 1}; {print}'

または:

sed -e '/^local/!b' -e 's/md5/trust/g;:1' -e 'n;b1'

SolarisまたはLinuxの両方で(bashまたはksh(または/usr/xpg4/bin/shSolarisのような)POSIXシェルから)POSIX準拠のユーティリティを確実に取得するには、次を追加できます。

PATH=$(command -p getconf PATH):$PATH

スクリプトの先頭に。またはcommand -p、POSIXバージョンが必要なすべてのコマンドの前に追加します。


助けてくれてありがとう、sed -e '/^local/!b' -e 's/md5/trust/g;:1' -e 'n;b1'うまくいく。しかし、GNU互換の行がスクリプトで機能せず、シェルで機能する理由を理解したいのです。そして、なぜ私はそれを使用することはできません/usr/lib/sed...
csny

1
@csny、動作し/usr/lib/sed --version、それがGNUだと言及していますか?truss -f /usr/lib/sed最終的にsedどこかで別の実行を示していますか?(/ usr / lib / sedが、環境に基づいてこれまたはsedを呼び出すラッパーであるように)?/ usr / lib / sedはスクリプトですか?
ステファンシャゼル14

申し訳ありませんが、私は意味/usr/bin/sed...
csny

バージョン:GNU sedバージョン4.1.5
csny 14

スクリプトにtruss -f sedを追加しましたが、そうではないことがわかりました/usr/bin/sedが、そうです/usr/xpg4/bin/sed
csny 14

0

以下に、別のポータブルな方法を示しますsed

sed 1i\\ file |
sed '1,/^local/s/md5/trust/;1d'

ちょっと息をする部屋を作ってください。ファイルの先頭に空白行が挿入されるため、1つまたは2つに頼ることができます。

あなたもするかもしれません:

{ echo; cat file; } |
sed '1,/^local/s/md5/trust/;1d'

呼び出すとき、おかげで、私はすでにこのための回避策を持っていますが、スクリプトはシェルプロンプトのような演技されていない理由を私はまだ理解できないsed...
csny

@csny- command -V sedプロンプトおよびスクリプト/非対話型シェルで試しましたか?たぶんalias | grep sed=インタラクティブなシェルからですか?
mikeserv

多分readlink /usr/bin/sed
mikeserv

待って... @csny-そのスクリプトにはシバンの行がありますか?頂点で?そのスクリプトを実行しているシェルは間違いなくありbashますか?lsof "$0"スクリプト内で何をするとどうなりますか?
mikeserv 14

#!/bin/bash上部にあります。シェルもbashです。lsof私のNexentaにはありません が、出力にps -efは次が含まれますroot 4949 4498 0 08:23:39 ? 0:00 /bin/bash /usr/local/ctera/bin/ctera.sh initdb。エイリアスない、といいえいいえreadlink... command -V sedでの結果/usr/bin/sed
csny 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.