AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / computer / Perguntas / 1882461
Accepted
pravi
pravi
Asked: 2025-02-24 00:03:41 +0800 CST2025-02-24 00:03:41 +0800 CST 2025-02-24 00:03:41 +0800 CST

Como esse operador de entrada padrão (0<) funciona no Linux?

  • 772

Supondo que haja dois arquivos no Linux. FileA e FileB, ambos com alguma lista diferente de frutas. Eu aplico os comandos abaixo.

diff fileA fileB > file.diff

Em seguida, executo o comando abaixo

patch fileA 0< file.diff

O comando acima corrige (corrige os erros) o arquivo original ( fileA ) da entrada dada por file.diff e envia a saída para fileA (é isso que eu entendi, posso estar errado). Em outras palavras, fileA e fileB correspondem.

"0<" é conhecido como um símbolo de redirecionamento para entrada padrão (até onde eu entendo). Agora, já que a entrada padrão é um teclado, o comando patch não deveria ler do teclado e não do file.diff ? Como o comando acima funciona?

linux
  • 4 4 respostas
  • 2001 Views

4 respostas

  • Voted
  1. Best Answer
    David Anderson
    2025-02-24T00:43:21+08:002025-02-24T00:43:21+08:00

    Esta resposta foi testada usando um shell Bash.

    Os comandos abaixo são os mesmos. O 1é o padrão e, portanto, pode ser omitido. Basicamente, a saída padrão de diffé redirecionada da tela para o arquivo file.diff.

    diff fileA fileB > file.diff
    diff fileA fileB 1> file.diff
    

    Os comandos abaixo são os mesmos. O 0é o padrão e, portanto, pode ser omitido. Basicamente, a entrada padrão para patché redirecionada do teclado para ser do arquivo file.diff.

    patch fileA 0< file.diff
    patch fileA < file.diff
    

    Tentarei explicar da seguinte forma. Quando entro no comando tty, obtenho a seguinte saída.

    /dev/pts/0
    

    Isso significa que a janela Terminal recebeu o nome de arquivo /dev/pts/0. Tanto a entrada padrão quanto a saída padrão receberam os nomes de arquivo /dev/fd/0e /dev/fd/1, respectivamente.

    O comando abaixo testa se a entrada padrão ( /dev/fd/0) e a janela Terminal ( /dev/pts/0) têm os mesmos valores de dispositivo e inode. Em outras palavras, teste para ver se eles são os mesmos. Neste caso, a saída é true.

    if [[ /dev/fd/0 -ef /dev/pts/0 ]]; then echo "true"; else echo "false"; fi
    

    O comando abaixo testa se a entrada padrão ( /dev/fd/0) e o arquivo file.difftêm os mesmos valores de dispositivo e inode. Neste caso, a saída é false.

    if [[ /dev/fd/0 -ef file.diff ]]; then echo "true"; else echo "false"; fi
    

    Entretanto, se a entrada padrão for redirecionada para vir do arquivo file.diff, como mostrado abaixo, então a saída será true.

    if [[ /dev/fd/0 -ef file.diff ]]; then echo "true"; else echo "false"; fi < file.diff
    

    Minha resposta até este ponto explicou o comportamento do redirecionamento ao usar um shell Bash. Esse comportamento deve ser consistente em todos os sistemas operacionais. Evitei detalhes de implementação, porque isso pode variar em diferentes sistemas operacionais. Você pode estar interessado em alguns detalhes de implementação, então apresento o seguinte para o Ubuntu Linux.

    A saída abaixo mostra que a entrada padrão ( /dev/fd/0) e a saída padrão ( /dev/fd/1) são links simbólicos para a janela do Terminal ( /dev/pts/0).

    sem redirecionamento

    Abaixo estão os resultados quando a entrada padrão é redirecionada para vir do arquivo file.diff. Agora, a entrada padrão ( /dev/fd/0) mudou para um link simbólico para o arquivo file.diff.

    redirecionamento

    • 10
  2. grawity
    2025-02-24T01:58:38+08:002025-02-24T01:58:38+08:00

    "0<" é conhecido como um símbolo de redirecionamento para entrada padrão (até onde eu entendo). Agora, já que a entrada padrão é um teclado, o comando patch não deveria ler do teclado e não do arquivo.diff? Como o comando acima funciona?

    Não. A entrada padrão é conectada ao teclado (ou mais precisamente ao dispositivo 'tty' através do qual o SO fornece entrada de teclado). A qualquer momento, a conexão pode ser fechada e outra coisa aberta em seu lugar – o termo "entrada padrão" se refere ao "slot" de conexão específico e não a onde ele vai. (É por isso que é chamado de "entrada padrão" e não "entrada de teclado".)

    Os números não são apenas sintaxe de shell; eles representam como os próprios programas trabalham com arquivos abertos. Dentro de cada processo, todo "arquivo aberto" é representado por um número (o descritor de arquivo , ou o handle como o Windows o chama) e todas as chamadas de leitura/gravação funcionam nesse número. Por convenção padrão, qualquer arquivo aberto que é atribuído ao descritor de arquivo 0é a "entrada padrão".

    Se você iniciar o programa a partir de um terminal, o "tty" do terminal será pré-aberto como FD 0– ou melhor, herdado do shell onde ele já estava aberto – e, portanto, será o stdin do programa. (O mesmo vale para 1stdout e 2stderr.) Então, o programa 'diff' precisará abrir alguns arquivos, então ele chamará open("fileA", ...)e o arquivo A será aberto como FD 3e assim por diante.

    Mas assim como o programa pode fechar qualquer arquivo que ele mesmo abriu (por exemplo, ele pode fechar o arquivo A executando close(3)), ele também pode close(0)fechar seu stdin e abrir outra coisa em seu lugar; desde que o arquivo recém-aberto receba o descritor de arquivo, 0ele é, por definição, "entrada padrão".

    O shell pode fazer o mesmo logo antes de iniciar o programa. Usar <file.diffou 0<file.diffsignifica que o shell fechará seu descritor de arquivo stdin original com close(0)e abrirá o arquivo open("file.diff")como o novo FD 0que então se torna o novo stdin, a ser herdado pelo programa 'diff'. (Isso acontece no processo filho que o shell cria para iniciar 'diff', sem afetar o processo principal do shell.) Agora, quando diff chama, read(0, …)ele lê do arquivo.


    Notas laterais:

    Geralmente open()usa o descritor de arquivo mais baixo disponível, por exemplo, se 0 acabou de ser fechado, então o próximo arquivo open()ed será 0 novamente. Se um controle mais preciso for necessário, dup2()pode ser usado para escolher um FD específico.

    É possível redirecionar qualquer descritor de arquivo, por exemplo, 5>file.txtdará ao programa um FD pré-aberto 5correspondente àquele arquivo, mas isso só é útil se o programa espera receber um; caso contrário, ele permanecerá aberto, mas não utilizado. (Alguns programas têm opções como gpg --status-fd=which podem ser usadas para passar FDs adicionais.)

    O Windows tem conceitos semelhantes e seu cmd.exe até tem a mesma 2>sintaxe, mas os identificadores de arquivo do Windows não são numerados a partir de 0 (eles são ponteiros de memória), então o cmd.exe implementa apenas 0/1/2 e os traduz para identificadores padrão no estilo Windows. (Enquanto isso, o PowerShell é um mundo estranho.)


    Semelhante ao exemplo que David Anderson deu, ls -l /proc/self/fd– somente no Linux – pode ser usado para inspecionar seus próprios descritores de arquivo, ou ls -l /proc/<pid>/fdpara qualquer outro processo. Por exemplo:

    $ ls -l /proc/self/fd 
    total 0
    lrwx------ 1  users 64 Feb 24 14:38 0 -> /dev/pts/4
    lrwx------ 1  users 64 Feb 24 14:38 1 -> /dev/pts/4
    lrwx------ 1  users 64 Feb 24 14:38 2 -> /dev/pts/4
    lr-x------ 1  users 64 Feb 24 14:38 3 -> /proc/833587/fd/
    

    Aqui os descritores de arquivo 0 (stdin), 1 (stdout), 2 (stderr) estão atualmente conectados ao terminal (todos herdados do shell), enquanto 3 foi aberto pelo próprio 'ls' e é, claro, o diretório que está sendo listado. Se você redirecionar stdin usando <, você obtém:

    $ ls -l /proc/self/fd < ~/test.c
    total 0
    lr-x------ 1  users 64 Feb 24 14:39 0 -> /home/grawity/test.c
    lrwx------ 1  users 64 Feb 24 14:39 1 -> /dev/pts/4
    lrwx------ 1  users 64 Feb 24 14:39 2 -> /dev/pts/4
    lr-x------ 1  users 64 Feb 24 14:39 3 -> /proc/833693/fd/
    

    E o mesmo com alguns descritores de arquivo inúteis fornecidos ao programa:

    $ ls -l /proc/self/fd 5< ~/test.c 9> /dev/null
    total 0
    lrwx------ 1  users 64 Feb 24 14:41 0 -> /dev/pts/4
    lrwx------ 1  users 64 Feb 24 14:41 1 -> /dev/pts/4
    lrwx------ 1  users 64 Feb 24 14:41 2 -> /dev/pts/4
    lr-x------ 1  users 64 Feb 24 14:41 3 -> /proc/833741/fd/
    lr-x------ 1  users 64 Feb 24 14:41 5 -> /home/grawity/test.c
    l-wx------ 1  users 64 Feb 24 14:41 9 -> /dev/null
    
    • 9
  3. Jasen
    2025-02-24T12:47:55+08:002025-02-24T12:47:55+08:00

    No Linux e outros sistemas operacionais do tipo Unix

    O que o shell faz quando quer executar outro programa é clonar uma cópia de si mesmo por uma chamada para fork()(isso pode parecer muito trabalho, mas através da mágica da cópia na escrita o esforço e o custo de recursos são muito reduzidos). Então essa cópia se substitui pelo programa que quer executar por uma chamada para exec()(a chamada real do SO é execve())

    No caso de redirecionamento de entrada ou saída ser necessário, a cópia bifurcada sabe disso e esses arquivos ou fluxos são abertos entre o fork()e o exec(), assim o shell original mantém sua conexão com os dispositivos de E/S originais, mas o ambiente no qual o novo programa é iniciado foi alterado.

    Isto é explicado em detalhes em LPG

    • 4
  4. Falco
    2025-02-24T17:40:40+08:002025-02-24T17:40:40+08:00

    O termo "redirecionamento" pode ser um pouco confuso, o que é redirecionado é a chamada de leitura do processo, porque a leitura de descritores de arquivo como STDIN é pull e não push. O processo puxa dados de "STDIN".

    Geralmente você tem uma conexão que conecta o STDIN ao seu teclado. Tudo o que você digitar no teclado será mantido em um buffer e quando o processo ler de "STDIN", ele lerá desse buffer e obterá as teclas que você digitou.

    Process --read-> STDIN --read-> Keyboard-Buffer

    Quando você inicia o processo com proc 0< file.diffisso, as chamadas de leitura do processo serão redirecionadas para STDIN para file.diff. Agora há uma conexão de STDIN para file.diff em vez do teclado.

    Process --read-> STDIN --read-> file.diff

    O processo ainda pode ler diretamente do buffer do teclado acessando algo como /dev/pts/0(dependendo do terminal), mas uma chamada para ler STDIN agora lerá de file.diff.

    • 0

relate perguntas

  • Como eu faria minha máquina Linux parecer que está executando o Windows?

  • Existe um equivalente a cd - para cp ou mv?

  • execute o contêiner do docker como root

  • Como ativar o sensor de impressão digital no domínio e no diretório ativo do Linux

  • Como alterar permanentemente Ctrl + C para Ctrl + K no CentOS 7?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como posso reduzir o consumo do processo `vmmem`?

    • 11 respostas
  • Marko Smith

    Baixar vídeo do Microsoft Stream

    • 4 respostas
  • Marko Smith

    O Google Chrome DevTools falhou ao analisar o SourceMap: chrome-extension

    • 6 respostas
  • Marko Smith

    O visualizador de fotos do Windows não pode ser executado porque não há memória suficiente?

    • 5 respostas
  • Marko Smith

    Como faço para ativar o WindowsXP agora que o suporte acabou?

    • 6 respostas
  • Marko Smith

    Área de trabalho remota congelando intermitentemente

    • 7 respostas
  • Marko Smith

    O que significa ter uma máscara de sub-rede /32?

    • 6 respostas
  • Marko Smith

    Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows?

    • 1 respostas
  • Marko Smith

    O VirtualBox falha ao iniciar com VERR_NEM_VM_CREATE_FAILED

    • 8 respostas
  • Marko Smith

    Os aplicativos não aparecem nas configurações de privacidade da câmera e do microfone no MacBook

    • 5 respostas
  • Martin Hope
    Vickel O Firefox não permite mais colar no WhatsApp web? 2023-08-18 05:04:35 +0800 CST
  • Martin Hope
    Saaru Lindestøkke Por que os arquivos tar.xz são 15x menores ao usar a biblioteca tar do Python em comparação com o tar do macOS? 2021-03-14 09:37:48 +0800 CST
  • Martin Hope
    CiaranWelsh Como posso reduzir o consumo do processo `vmmem`? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Pesquisa do Windows 10 não está carregando, mostrando janela em branco 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    andre_ss6 Área de trabalho remota congelando intermitentemente 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney Por que colocar um ponto após o URL remove as informações de login? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca Todos os meus complementos do Firefox foram desativados repentinamente, como posso reativá-los? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK É possível criar um código QR usando texto? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 Altere o nome da ramificação padrão do git init 2019-04-01 06:16:56 +0800 CST

Hot tag

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve