Como passar argumentos para um processo Java a partir de um script de shell [closed]

0

Isso pode ser uma duplicação, mas as perguntas iniciais que encontrei a resposta não resolveram o problema.

Ainda outra reescrita da pergunta.

Eu tenho este aplicativo Java:

public static void main(final String[] args) {
    System.out.println("DEBUG: arguments passed to the main - " + Arrays.toString(args));
    System.exit(new TaskRunner().run(args));
}

Se eu chamar o código diretamente com dois argumentos:

$ nohup ${JAVA_HOME}/bin/java -cp /opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/* wib.runner.TaskRunner -taskExtRef "QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities" > /opt/sw/calypso/logs/taskrunner/log.direct.log 2>&1

imprime

[TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD IPV - EOD Rates Input - Commodities Volatilities]

que é o que eu espero. Mas se eu escrever este script de shell ( startScheduledTask.sh ):

NOW_DATE='date '+%Y%m%d%H%M%S''

nohup ${JAVA_HOME}/bin/java -cp some:classpath:values package.name.classname "$@"   > /opt/random/path/tplogs/classname/${aVariableLogName}.${NOW_DATE}.log 2>&1

e execute-o como

$ ./startScheduledTask.sh -taskExtRef "QUOTES_UPLOAD IPV - EOD Rates Input -   Commodities Volatilities" &

Eu recebo esta saída:

[TaskRunner] DEBUG: : arguments passed to the main - [-taskExtRef, QUOTES_UPLOAD, IPV, -, EOD, Rates, Input, -, Commodities, Volatilities]

(ou seja, o segundo argumento é dividido em nove argumentos, porque contém oito espaços). Portanto, acredito que o roteiro está errado.

Como corrijo isso?

    
por GvD 28.08.2015 / 07:16

1 resposta

2

Quando o shell analisa uma linha de comando, remove citações, mas lembra a estrutura de texto que elas implicam. (Isso é uma simplificação grosseira; veja bash (1) ou Idioma de comando do shell para mais detalhes.) Por exemplo, a entrada da linha de comandos

-blah apple -secondfruit "green banana" -some more

faz com que o shell identifique seis palavras ou tokens:

  1. -blah
  2. apple
  3. -secondfruit
  4. green banana
  5. -some
  6. more

que será armazenado na memória como

-blahⓧappleⓧ-secondfruitⓧgreen bananaⓧ-someⓧmoreⓧ

em que representa um byte nulo. Isso, por vezes, será exibido ou relatado como

-blah apple -secondfruit green banana -some more

para que você possa acreditar que as citações estão sendo ignoradas, e você tem sete palavras, enquanto, na verdade, você tem o que quer.

Note:

In the above, represents a null byte.  What I'm describing here is standard shell argument-parsing processing.  If you type

ls -l fruit.sh "I came here for an argument" startScheduledTask.sh

the /bin/ls program gets invoked with the string

lsⓧ-lⓧfruit.shⓧI came here for an argumentⓧstartScheduledTask.shⓧ

in memory, and this gets interpreted as

  • argv[0] = ls
  • argv[1] = -l
  • argv[2] = fruit.sh
  • argv[3] = I came here for an argument
  • argv[4] = startScheduledTask.sh

This exact same process happens if you are

  1. typing a java command directly into your primary, interactive shell,
  2. executing a java command that is in a shell script, or
  3. running a shell script by typing a command like ./startScheduledTask.sh directly into your primary, interactive shell,

so this is not the problem.  Any program that cannot handle having its arguments separated by null characters cannot work in Unix & Linux.

TL; DR

Seu primeiro comando está correto. "$@" te dá o que você quer; é a maneira correta de um script de shell passar seus argumentos para um programa que ele chama. Se você adicionar código de depuração ao seu programa para percorrer seus argumentos, imprimindo cada um em uma nova linha, e / ou entre colchetes (mas não todos em uma linha, separados apenas por espaços), você verá que o "$@" está passando seis argumentos para o programa.

OK, ainda mais:

  • Seu caminho de classe tem asteriscos ( * s) nele? Mesmo? Estou um pouco sem prática com o Java, mas isso parece estranho para mim. Verifique novamente se você está fazendo isso corretamente no seu sistema. Mas, se funciona corretamente quando você digita o caminho de classe com asteriscos "diretamente" (ou seja, diretamente no seu shell principal; seu shell primário e interativo; seu shell de login), então, provavelmente, não é o problema.

    Mas, por favor, humorize-me e coloque essa string entre aspas, de qualquer forma.

  • Seu problema é muito complicado. Quando você está construindo um avião, você não constrói o avião inteiro e tenta voar. E então, quando ele não voa, você não recua e pergunta, "O que há de errado com o avião?" Não, você testa em pedaços. Você precisa simplificar.

    • Pare de executá-lo em segundo plano.
    • Pare de dizer nohup .
    • Pare de redirecionar a saída.
    • Não mostre seu prompt de 42 caracteres em sua pergunta.
    • Sua pergunta é sobre um argumento com espaços, então não tire isso, mas não precisa ter 60 caracteres com oito espaços. green banana é um valor de teste ótimo .
    • Experimente com argumentos para o seu programa não começando com - (traço).
    • Talvez até comente a parte new TaskRunner().run(args) do seu programa, deixando apenas o DEBUG e System.exit(0); .

    Nenhum desses deve fazer a diferença. Mas são distrações que dificultam ver o que é importante. Se você puder demonstrar o problema em uma configuração de teste mínima, podemos descartar todas essas outras coisas como sendo relacionadas ao problema. Mas, se o problema desaparecer quando você remover as coisas irrelevantes, então um deles provavelmente estava causando o problema.

    Além disso, pare de misturar dados falsos / de teste e dados reais (isto é, frutas e tarefas) na pergunta.

  • Por favor, escreva este script (chame-o fruity.sh ):

    #!/bin/sh
    
                    # classpath
    CP="/opt/fxudply/fxcal-client-jar/current/lib:/opt/fxudply/fxcal-client-jar/current/lib/*:/opt/fxudply/fxcal-config/current/wib-config:/opt/fxudply/fxcal-config/current/wib-config/*"
                    # package.name.classname
    PC=wib.runner.TaskRunner
    
    "$JAVA_HOME"/bin/java  -cp "$CP"  "$PC"  "$@"
    

    e execute

    ./fruity.sh taskExtRef "green banana"
    

    Se a depuração diz

    …[taskExtRef, green banana]
    

    o "$@" está funcionando corretamente e o problema está em outro lugar no seu roteiro. Tente encontrar. Faça uma alteração de cada vez e veja como o comportamento muda. Se você não consegue descobrir, podemos ajudá-lo mas somente se você nos mostrar a parte do script que está causando o problema.

    Mas se a depuração diz

    …[taskExtRef, green, banana]
    

    depois, informe-nos.

por 28.08.2015 / 07:59

Tags