O script Nexenta bash usa / usr / sun / bin / sed em vez de / usr / bin / sed

3

Estou usando um script para Linux e Solaris (Nexenta).

Esta linha funciona no Linux, mas não no solaris (mas quando executado a partir do shell, funciona):

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

A mensagem de erro é:

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

Após algumas pesquisas, descobri que o sed que o bash usa no script é diferente.

do shell: /usr/bin/sed

do script: /usr/sun/bin/sed

Eu quero fazer o script usar /usr/bin/sed .

O que tentei fazer:

  1. chame sed com o caminho completo. Mesmos resultados Parece que ainda usa os outros sed ...
  2. tentou ligar por meio de bash -l . Mesmos resultados.
  3. tentou declarar um comando diferente: S=/usr/lib/sed e use $S . Mesmos resultados.
  4. verificado PATH - o cmd e o script têm /usr/bin .
  5. Tentei substituir as aspas duplas por simples. Mesmos resultados.
  6. tentou executar o sed com o sinalizador -r. A saída é:

    # /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...]

AJUDA ??

O que eu preciso fazer é substituir a primeira correspondência de "md5" com "confiança" na primeira linha que começa com "local"). Eu sei que posso fazer de outra forma, mas eu a questão sed está me coçando muito!

EDIT:

Espero que isso faça um pouco de ordem ...

  1. CAMINHO do shell de login = /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. CAMINHO do script =
    /usr/sbin:/usr/bin:/usr/local/ctera/apache-ant-1.8.2/bin:/usr/local/ctera/apache-ant-1.8.2/bin
  3. CAMINHO do script quando PATH=$(command -p getconf PATH):$PATH é chamado = /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 das chamadas de shell de login /usr/bin/sed
  5. truss -f sed das chamadas de script /usr/sun/bin/sed
  6. truss -f /usr/bin/sed das chamadas de script /usr/sun/bin/sed !!!
  7. Depois de definir PATH=$(command -p getconf PATH):$PATH :
    7,1 truss -f sed das chamadas de script /usr/xpg4/bin/sed
    7,2 truss -f /usr/bin/sed das chamadas de script /usr/sun/bin/sed !!!

MAIS INFORMAÇÃO:

Comandos de saída: (executados a partir do prompt do shell e do script)

  1. truss -ft execve /usr/bin/sed q
    como comando shell:
    8604: execve("/usr/bin/sed", 0x08047D20, 0x08047D2C) argc = 2
    do script:% 8545: execve("/usr/sun/bin/sed", 0x08047768, 0x08047774) argc = 2

  2. file /usr/bin/sed
    como comando shell:
    /usr/bin/sed: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped
    do script:% 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
    como comando shell:
    -rwxr-xr-x 1 root root 96440 May 31 2008 /usr/bin/sed
    do script:% -rwxr-xr-x 1 root root 96440 May 31 2008 /usr/bin/sed

  4. ls -ld $(type -pa sed)
    como comando shell:
    -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
    do script:% -rwxr-xr-x 1 root root 96440 May 31 2008 /usr/bin/sed

  5. md5sum $(type -pa sed)
    como comando shell:
    385361c5111226c8eac8e25b53fed29c /bin/sed 385361c5111226c8eac8e25b53fed29c /usr/bin/sed
    do script: 385361c5111226c8eac8e25b53fed29c /usr/bin/sed

    • O script é invocado pelo código JAVA.

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

    • Isso pode adicionar informações sobre a versão sed na minha máquina

      ~# 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  
      
por csny 18.08.2014 / 17:47

3 respostas

2

OK, achei. Isso agora faz sentido.

o comportamento é específico do Nexenta e explicado no link

GNU and not GNU

The default behavior of Nexenta is to prefer GNU utilities, which are installed in /usr/bin and /usr/sbin and so on. The Sun versions of these utilities are installed in /usr/sun/bin and /usr/sun/sbin. Nexenta uses a trick to be able to switch between a GNU and a SUN personality: if the environment variable SUN_PERSONALITY is set to one, the search paths /usr/sun/bin and /usr/sun/sbin take preference, even if the user executes the commands explicitly by their absolute path, e.g. /usr/bin/sed. This ensures that Solaris-based scripts work in Nexenta without modifications. Nexenta also uses this functionality in its SVR4 package commands. They can be used to install native Solaris packages in SVR4 format, calling alien to convert the package on-the-fly to a Debian package.

Isso é feito em algum lugar na libc.

Então,

$ 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

Assim, seu script iniciado a partir do Java deve ter o conjunto SUN_PERSONALITY.

Você pode desmarcar isso no seu script se quiser as ferramentas GNU.

    
por 19.08.2014 / 23:16
2

Em qualquer caso,

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

É específico do GNU (o 0 address e o ; antes do } ) e não funciona com nenhuma outra implementação sed (e o Solaris não é fornecido com o GNU sed por padrão) .

Portável / padrão:

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

para substituir apenas as linhas até (mas não incluídas) a primeira começando com local . Ou:

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

(no Solaris, você pode precisar de command -p awk ).

Se você quiser a substituição na primeira linha que corresponde a /^local/ :

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

Ou:

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

Para ter certeza de obter utilitários compatíveis com POSIX tanto no Solaris quanto no Linux (a partir de um shell POSIX como bash ou ksh (ou /usr/xpg4/bin/sh no Solaris)), você pode adicionar:

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

para o topo do script. Ou adicione command -p na frente de cada comando do qual você deseja a versão POSIX.

    
por 18.08.2014 / 17:55
0

Aqui está outra maneira portátil de fazer isso com sed :

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

Apenas se dê um pouco de espaço para respirar. Isso insere uma linha em branco na cabeça do arquivo para que você possa confiar em uma coisa ou duas.

Você também pode fazer:

{ echo; cat file; } |
sed '1,/^local/s/md5/trust/;1d'
    
por 19.08.2014 / 14:17