Existem convenções aceitas para argv, opções, variáveis de ambiente, stdin, stdout e stderr ao construir CLIs?

3

Eu costumo falar sobre como simples aplicações de linha de comando são. Geralmente, eu digo algo como "eles lêem do padrão e escrevem para padrão e erro padrão, é isso." Então, eu desenho uma foto como:

Masentãocomeceiapensarquenãoérealmenteofimdahistória.Aplicativosdelinhadecomandolidosdopadrãoegravadosnoerropadrãoesaídapadrão,e...

  • leiaarquivosdeconfiguração(dequalquernúmerodelugares,como/etc,~ou.)
  • leiaasvariáveisdeambiente
  • lerasopçõesdalinhadecomando
  • lersinalizadoresdelinhadecomando
  • lerargumentosdalinhadecomando
  • definirostatusdesaída

Umaplicativodelinhadecomandoacabaparecendomaiscom:

Queéobjetivamentemaiscomplexodoquesimplesmentestdin,stdoutestderr.

Euusoaplicativosdelinhadecomandodurantetodoodia.Comotempo,desenvolviumaopiniãoeumaintuiçãosobreeles:

  • padrãoem-geralmentedados,nãoargumentos(amenosqueeuusexargs)
  • padrão-oproduto,depreferênciadadosemcoluna
  • erropadrão-pararegistrarmensagensdeerrooudeerrosealgodererrado
  • ostatusdesaída-sagrado,seja0parasucessoou1parafalha(ououtracoisaparaalgumoutrotipodefalha)
  • argumentos-importantes,maslidosdemaneiradiferentedopadrãoem
  • sinalizaargumentoscomomenosimportantes
  • comutadores-comosinalizadores,masestãoativadosoudesativados
  • variáveisdeambiente-maisoumenoscomoargumentos,masháalgumtipodediferençafilosóficaentreeles
  • arquivosdeconfiguração-comovariáveisdeambientenosentidodecontrolarinterruptoresousinalizadores,masvocêpodemantê-losnocontroledeversãoegeralmenteusá-losparaevitarterqueusarcombinaçõesfrustrantesdecomutadoresesinalizadoresoumostraratodoscomolegalseusdotfilessão

Essasdiretrizestendemafuncionarcomváriasferramentasdelinhadecomandoqueuso.Noentanto,quandosetratadeusá-losparaoutraspessoas,gostariadeterumareferência.

Porexemplo,oseguinteéumaplicativodelinhadecomandoescritocomRuby:

#!/usr/bin/envruby#someclirequire'optparse'require'yaml'options={}etc_config=File.join('etc','somecli')ifFile.exist?etc_configoptions.merge!YAML.load_file(etc_config)endhome_config=File.join(ENV['HOME'],'.somecli')ifFile.exist?home_configoptions.merge!YAML.load_file(home_config)endcurrent_working_directory_config='.somecli'ifFile.exist?current_working_directory_configoptions.merge!YAML.load_file(current_working_directory_config)endOptionParser.newdo|opts|opts.on("-s", "--[no-]switch") do |s|
    options[:switch] = s
  end
  opts.on("-a", "--[no-]another-switch") do |as|
    options[:'another-switch'] = as
  end
  opts.on("-y", "--[no-]yet-another-switch") do |yas|
    options[:'yet-another-switch'] = yas
  end
  opts.on("-y", "--[no-]even-yet-another-switch") do |eyas|
    options[:'even-yet-another-switch'] = eyas
  end
  opts.on("--flag FLAG") do |f|
    options[:flag] = f
  end
end.parse!

puts "ARGV=#{ARGV.inspect}"
puts "options=#{options.inspect}"
puts "ENV['cats']=#{ENV['cats'].inspect}"
unless STDIN.tty?
  puts "STDIN.read=#{STDIN.read.inspect}"
end
$stderr.puts "stderr: hello world!"
$stdout.puts "stdout: hello world!"
exit 0

Quando executado, parece

echo -n foo bar baz | ./somecli -s -f flap jacks; echo $?
ARGV=["jacks"]
options={:"another-switch"=>true, :"even-yet-another-switch"=>true, :switch=>true, :flag=>"flap"}
ENV['cats']="flapjacks"
STDIN.read="foo bar baz"
stderr: hello world!
stdout: hello world!
0

Gostaria de ter um link no README para um documento mais oficial que orientasse suas convenções de entrada e saída e decisões de design.

Eu sei que POSIX existe para decidir quais programas utilitários comuns estão instalados em um sistema , exceto eu estou querendo saber 2 coisas quando se trata de construir aplicações de linha de comando:

  1. Existem outras maneiras comuns de obter entrada em um programa de linha de comando que eu perdi?
  2. A documentação autoritativa existe para convenções sobre como organizar as várias entradas e saídas?
por mbigras 16.03.2018 / 03:27

2 respostas

2

Existem algumas diretrizes gerais para utilitários de linha de comando documentadas em POSIX.1 / Single UNIX Specification.

Veja Seção 12.2: Diretrizes da Sintaxe de Utilidade .

    
por 13.04.2018 / 04:10
1

Eu não acho que existam convenções a não ser o bom senso.

Quanto aos métodos de entrada e saída, ou em geral, métodos de comunicação , há um que você mencionou, mas apenas parcialmente. Está lendo e escrevendo em arquivos. (Você mencionou a leitura de arquivos de configuração ou, em geral, descritores de arquivos .)

Coisas semelhantes aos arquivos são pipes e soquetes. Por exemplo. Soquetes TCP, UDP ou Unix, que podem ser considerados uma forma de Comunicação entre Processos (IPC) . Outros tipos de IPC incluem:

  • memória compartilhada e mapeada
  • sinais
  • semáforos
  • D-Bus
por 16.03.2018 / 19:50