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 / user-289772

user938271's questions

Martin Hope
user938271
Asked: 2020-01-06 00:24:39 +0800 CST

Qual é a diferença entre os valores "off" e "external" para a opção "set-clipboard" no Tmux?

  • 4

De man tmux:

set-clipboard [on | external | off]

        Attempt to set the terminal clipboard content using the xterm(1)
        escape sequence, if there is an Ms entry in the terminfo(5)
        description (see the TERMINFO EXTENSIONS section).

        If set to on, tmux will both accept the escape sequence to create
        a buffer and attempt to set the terminal clipboard.  If set to
        external, tmux will attempt to set the terminal clipboard but
        ignore attempts by applications to set tmux buffers.  If off,
        tmux will neither accept the clipboard escape sequence nor
        attempt to set the clipboard.

        Note that this feature needs to be enabled in xterm(1) by setting
        the resource:

              disallowedWindowOps: 20,21,SetXprop

        Or changing this property from the xterm(1) interactive menu when
        required.

É assim que entendo a documentação; quando o Tmux recebe uma sequência codificada usando a Mscapacidade do terminal externo:

  • se set-clipboardfor definido como on, a sequência é usada para definir a área de transferência do terminal e um buffer Tmux

  • se set-clipboardestiver definido como off, a sequência não é usada para definir a área de transferência do terminal nem um buffer Tmux

  • se set-clipboardestiver definido como external, a sequência é usada para definir a área de transferência do terminal, mas não um buffer Tmux

Estou usando o XTerm (patch 322), com $TERMdefinido como xterm-256color, e aqui está sua descrição terminfo conforme relatado por $ infocmp -1x xterm-256color. Em particular, sua Mscapacidade é definida assim:

Ms=\E]52;%p1%s;%p2%s\007

Eu só tenho essas 3 linhas dentro ~/.Xresources:

XTerm*termName: xterm-256color
XTerm*disallowedWindowOps: 20,21,SetXprop
XTerm*selectToClipboard: true

Eu inicio o Tmux sem configuração:

$ tmux -Lx -f/dev/null

Eu configurei set-clipboardpara on:

$ tmux set -s set-clipboard on

Eu envio uma sequência OSC 52 para o Tmux printfcontendo o texto test on:

$ printf '\e]52;c;%s\007' $(printf 'test on' | base64)

O resultado é que o Tmux criou um buffer interno e enviou a sequência OSC 52 para o XTerm que preencheu sua área de transferência com test on:

$ tmux lsb
buffer0: 7 bytes: "test on"

$ xsel -b
test on

Agora eu resetei set-clipboardpara off:

$ tmux set -s set-clipboard off

Eu envio uma sequência OSC 52 para o Tmux printfcontendo o texto test off:

$ printf '\e]52;c;%s\007' $(printf 'test off' | base64)

Desta vez, o Tmux não criou um novo buffer interno e não enviou a sequência OSC 52 para o XTerm:

$ xsel -b
test on

$ tmux lsb
buffer0: 7 bytes: "test on"

Caso contrário, uma das saídas desses 2 comandos shell incluiria test off.


Por fim, reiniciei set-clipboardpara external:

$ tmux set -s set-clipboard external

Eu envio uma sequência OSC 52 para o Tmux printfcontendo o texto test external:

$ printf '\e]52;c;%s\007' $(printf 'test external' | base64)

O Tmux não criou um novo buffer interno e não enviou a sequência OSC 52 para o XTerm:

$ xsel -b
test on

$ tmux lsb
buffer0: 7 bytes: "test on"

Caso contrário, uma das saídas desses 2 comandos shell incluiria test external.


Entendo os resultados quando defino set-clipboardcomo one para off, mas não entendo o resultado quando defino como external. Com base nesta frase da página de manual do Tmux:

Se definido como externo, o tmux tentará definir a área de transferência do terminal, mas ignorará as tentativas dos aplicativos de definir os buffers do tmux.

Eu esperava que o Tmux enviasse a sequência OSC 52 para o XTerm, sem criar um buffer interno. Na prática, ele não cria um buffer interno (esperado), mas também não envia a sequência OSC 52 para o XTerm (inesperado).

Devo ter entendido mal essa frase. Qual experimento eu poderia realizar para observar uma diferença entre os valores externale off?

tmux
  • 1 respostas
  • 528 Views
Martin Hope
user938271
Asked: 2019-11-07 01:15:54 +0800 CST

Como se referir à raiz da cauda de um caminho em um comando zsh?

  • 3

Costumo clonar um repositório git e entrar em seu diretório raiz. Por exemplo:

$ git clone https://github.com/hpjansson/chafa && cd chafa

Para tornar isso um pouco mais fácil, tenho uma abreviação zsh – cc– que é expandida para && cd !#:2:t:

typeset -Ag abbrev
abbrev=(
  'G' '| grep -v grep | grep'
  'L' '2>&1 | less'
  'V' '2>&1 | vipe >/dev/null'
  'ac' '| column -t'
  'bl' '; tput bel'
  'cc' '&& cd !#:2:t'
  'fl' "| awk '{ print $"
  'ne' '2>/dev/null'
  'pf' "printf -- '"
  'sl' '>/dev/null 2>&1'
  'tl' '| tail -20'
)
__abbrev_expand() {
  emulate -L zsh
  setopt EXTENDED_GLOB
  local MATCH
  LBUFFER=${LBUFFER%%(#m)[a-zA-Z]#}
  if [[ "${LBUFFER: -1}" == ' ' ]]; then
    LBUFFER+=${abbrev[$MATCH]:-$MATCH}
    if [[ $MATCH = 'fl' ]]; then
      RBUFFER="}'"
    elif [[ $MATCH = 'pf' ]]; then
      RBUFFER="\n'"
    fi
  else
    LBUFFER+=$MATCH
  fi
  zle self-insert
}
zle -N __abbrev_expand
bindkey ' ' __abbrev_expand
bindkey -M isearch ' ' self-insert

!#refere-se à linha de comando atual, conforme descrito em man zshexpn(seção HISTORY EXPANSION, subseção Event Designators):

!# Consulte a linha de comando atual digitada até agora. A linha é tratada como se estivesse completa até e incluindo a palavra anterior àquela com a !#referência.

:2refere-se à segunda palavra na linha de comando (que é a url quando digito um $ git clonecomando):

n O enésimo argumento.

E :tse refere à cauda dessa palavra:

t Remova todos os componentes principais do nome do caminho, deixando a cauda. Isso funciona como basename.


Normalmente, digito git clonena linha de comando, copio e colo a url do projeto e insiro um espaço cce outro espaço, que fornece o comando desejado.

No entanto, às vezes, o URL que eu copio e colo termina com a extensão .git. Quando isso acontece, a expansão de !#:2:tcontém uma .gitextensão indesejável:

$ git clone https://github.com/hpjansson/chafa.git cc
→
$ git clone https://github.com/hpjansson/chafa.git && cd !#:2:t
→
$ git clone https://github.com/hpjansson/chafa.git && cd chafa.git
cd: no such file or directory: chafa.git

Uma solução é também usar o :rmodificador para remover a .gitextensão:

r Remova uma extensão de nome de arquivo deixando o nome raiz. Strings sem extensão de nome de arquivo não são alteradas. Uma extensão de nome de arquivo é .seguida por qualquer número de caracteres (incluindo zero) que não são nem . nem / e que continuam até o final da string. Por exemplo, a extensão de foo.orig.cé .c, e dir.c/foonão tem extensão.

                                                               vv
$ git clone https://github.com/hpjansson/chafa.git && cd !#:2:t:r
→
$ git clone https://github.com/hpjansson/chafa.git && cd chafa

No entanto, se o caminho não terminar com uma .gitextensão, a expansão falhará e nem o gitcomando nem o cdcomando serão executados.

Aqui está um exemplo mínimo para ilustrar o problema:

$ echo /foo/bar.baz !#:1:t:r
/foo/bar.baz bar

$ echo /foo/bar !#:1:t:r
zsh: modifier failed: r

O primeiro comando é bem-sucedido porque o último componente do caminho contém a extensão .baz, mas o segundo falha porque não há mais extensão. OTOH, em bash 4.3.48, ambos os comandos funcionam conforme o esperado.

Não entendo por que :rfalha quando não há extensão, pois sua documentação contém esta frase:

Strings sem extensão de nome de arquivo não são alteradas.

Não diz que usar :rpara uma string que não contém uma extensão é um erro.


Tentei outra abordagem; removendo a extensão com o :smodificador. Eu acho que isso requer que a HIST_SUBST_PATTERNopção seja definida:

setopt HIST_SUBST_PATTERN

Com esta opção, pode-se escrever :s/.*para remover uma extensão:

                          vvvvv
$ echo /foo/bar.baz !#:1:t:s/.*
/foo/bar.baz bar

Funciona quando há uma extensão, mas novamente falha quando não há nenhuma:

$ setopt HIST_SUBST_PATTERN
$ echo /foo/bar !#:1:t:s/.*
zsh: substitution failed

Existe uma única sequência de modificadores que podem se referir simultaneamente a barin /foo/bar.baze a barin /foo/bar?

estou usando zsh 5.7.1-dev-0 (x86_64-pc-linux-gnu).

zsh
  • 1 respostas
  • 425 Views
Martin Hope
user938271
Asked: 2019-09-14 03:19:52 +0800 CST

Como evitar que o nome de uma página de manual seja truncado ao usar o Vim como um pager de manual?

  • 1

Considere este comando shell:

$ MANPAGER='vim -Nu NONE -R -' man git-credential-cache

Faz man(1)exibir a página de manual do git-credential-cache(1)Vim.

No entanto, o nome da página man – conforme exibido na primeira linha do buffer – é GIT-CREDENTIAL-CAC(1). Observe como HEestá faltando no final do nome:

o nome da página de manual do git-credential-cache está faltando seus dois últimos caracteres

Eu esperaria este nome em vez disso:

GIT-CREDENTIAL-CACHE(1)
                  ^^

Corri strace(1)para ver quais chamadas de sistema foram usadas por man(1):

$ MANPAGER='vim -Nu NONE -R -' strace -o log man git-credential-cache

No final do arquivo de log, posso ver uma chamada de sistema read(2)e write(2), usando o nome do buffer GIT-CREDENTIAL-CAC(1):

read(7, "GIT-CREDENTIAL-CAC(1)           "..., 4096) = 2720
...
write(8, "GIT-CREDENTIAL-CAC(1)           "..., 2720) = 2720

Então parece que é man(1)e não vim(1)que está truncando o nome da página de manual.

Aqui está o conteúdo completo do arquivo de log , outro arquivo de log contendo a saída do mesmo strace(1)comando, mas com o -fargumento adicional para rastrear também os processos filhos e a árvore de processos que leva ao man(1)processo:

$ pstree -lsp $(pidof man)
systemd(1)---lightdm(947)---lightdm(1114)---upstart(1123)---sh(1324)---xfce4-session(1335)---xfce4-panel(1347)---panel-8-whisker(1396)---xterm(22546)---bash(22547)---strace(23182)---man(23184)---vim(23194)

Existe uma maneira de evitar man(1)truncar GIT-CREDENTIAL-CACHE(1)em GIT-CREDENTIAL-CAC(1)?

A razão pela qual faço esta pergunta é porque o truncamento faz com que uma mensagem de erro seja exibida ao usar o plug-in do Neovim man :

            ┌ Taken from `:h man.vim` in Neovim
            ├────────┐
$ MANPAGER='nvim +Man!' man git-credential-cache
man.vim: command error (7) man -w git-credential-cac: No manual entry for git-credential-cac

erro no Neovim devido ao truncamento do nome da página man


Meio Ambiente:

$  lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:        16.04
Codename:       xenial

$ man --version
man 2.7.5

$ vim --version | head -n2
VIM - Vi IMproved 8.1 (2018 May 18, compiled Sep  3 2019 11:05:36)
Included patches: 1-1967

$ nvim --version | head -n1
NVIM v0.4.0-1856-g82d52b229
vim
  • 1 respostas
  • 130 Views
Martin Hope
user938271
Asked: 2019-08-09 13:12:49 +0800 CST

Por que preciso inserir 12 caracteres para limpar esta linha de comando bash?

  • 15

Abro um terminal xterm (80 colunas x 24 linhas), depois executo $ bash --norc --noprofilee, em seguida, $ ttypara obter o nome do arquivo do terminal: a saída é /dev/pts/9.

De outro terminal eu corro:

$ printf foo >/dev/pts/9

fooé impresso na linha de comando do shell no primeiro terminal.
Se eu pressionar C-upara executar unix-line-discard(nome da função dado por $ bind -P | grep -i c-u), foonão é removido.
Se eu inserir 11 espaços e pressionar C-u, os espaços serão removidos, mas não foo.
Se eu inserir 12 espaços e pressionar C-u, os espaços serão removidos assim como foo.

insira a descrição da imagem aqui

Por que não consigo remover fooquando pressiono C-uenquanto meu cursor está logo após e por que preciso inserir 12 caracteres para removê-lo?


Meio Ambiente:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:        16.04
Codename:       xenial

$ bash --version | head -n1
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

$ xterm -version
XTerm(322)
bash terminal-emulator
  • 1 respostas
  • 5144 Views
Martin Hope
user938271
Asked: 2019-02-27 05:11:51 +0800 CST

Por que o gawk trata `0123` como um número decimal quando vem dos dados de entrada?

  • 5

De acordo com $ man gawk, a strtonum()função pode converter uma string em um número:

strtonum(str) Examine str e retorne seu valor numérico. Se str começar com um 0 inicial, trate-o como um número octal. Se str começar com 0x ou 0X à esquerda, trate-o como um número hexadecimal. Caso contrário, assuma que é um número decimal.

E se a string começa com um 0, o número é tratado como octal, enquanto se começa com 0xé tratado como hexadecimal.

Eu executei estes comandos para verificar minha compreensão da função:

$ awk 'END { print strtonum("0123") }' <<<''
83

$ awk 'END { print strtonum("0x123") }' <<<''
291

A string "0123"é tratada corretamente como contendo um número octal e convertida no número decimal 83. Da mesma forma, a string "0x123"é tratada corretamente como contendo um número hexadecimal e convertida no número decimal 291.

Agora, aqui está o que acontece se eu executar os mesmos comandos, mas movendo as strings numéricas do texto do programa para os dados de entrada:

$ awk 'END { print strtonum($1) }' <<<'0123'
123

$ awk 'END { print strtonum($1) }' <<<'0x123'
291

Eu entendo o segundo resultado que é idêntico aos comandos anteriores, mas não entendo o primeiro. Por que o gawk agora trata 0123como um número decimal, mesmo que comece com uma entrelinha 0que caracteriza os números octais?

Suspeito que tenha algo a ver com o atributo strnum , porque por algum motivo 1 , gawk fornece esse atributo para , 0123mas não para 0x123:

$ awk 'END { print typeof($1) }' <<<'0123'
strnum

$ awk 'END { print typeof($1) }' <<<'0x123'
string

1 Pode ser devido a uma variação entre as implementações do awk:

Para esclarecer, apenas strings provenientes de algumas fontes (aqui citando a especificação POSIX): [...] devem ser consideradas uma string numérica se seu valor for numérico (permitindo espaços em branco à esquerda e à direita, com variações entre as implementações em suporte para hex, octal , inf, nan...).


Estou usando gawk version 4.2.62e a saída de $ awk -Vé:

GNU Awk 4.2.62, API: 2.0 (GNU MPFR 3.1.4, GNU MP 6.1.0)
input gawk
  • 1 respostas
  • 344 Views
Martin Hope
user938271
Asked: 2018-11-29 13:06:05 +0800 CST

Como evitar que o Vim traduza Cj em Cm quando iniciado pelo widget zle `edit-command-line`?

  • 3

Tenho o seguinte código no meu ~/.zshrc:

autoload -Uz edit-command-line
zle -N edit-command-line
bindkey '^X^E' edit-command-line

Ele liga o edit-command-linewidget zle à sequência de teclas C-x C-e. O widget é descrito em man zshcontrib(seção ZLE FUNCTIONS, subseção Widgets):

edit-command-line Edite a linha de comando usando seu editor visual, como em ksh.

          bindkey -M vicmd v edit-command-line

O objetivo é poder editar a linha de comando do shell atual, no editor padrão, pressionando C-x C-e, semelhante ao que a função readline edit-and-execute-commandfaz ( man bash, section READLINE, subsection Commands for Manipulating the History).

comando edit-and-execute (C-xC-e) Chama um editor na linha de comando atual e executa o resultado como comandos shell. O Bash tenta invocar $VISUAL, $EDITOR e emacs como editor, nessa ordem.

Meu editor padrão é o Vim 8.1(patches 1-538incluídos). Eu tenho mapeamentos do Vim, usando as teclas C-h, C-j, C-k, C-l, para mover o foco para as janelas vizinhas. Eles podem ser reduzidos a:

nnoremap <c-h> :<c-u>wincmd h<cr>
nnoremap <c-j> :<c-u>wincmd j<cr>
nnoremap <c-k> :<c-u>wincmd k<cr>
nnoremap <c-l> :<c-u>wincmd l<cr>

Todos eles funcionam como esperado em uma instância regular do Vim (iniciada executando $ vim). Mas C-jnão funciona como esperado quando o Vim foi iniciado por edit-command-line.

Quando pressiono C-x C-ewhile na linha de comando do shell, o zsh inicia o Vim. Se eu dividir a janela executando :split, pressione C-kpara mover para a janela superior, recebo duas janelas e o foco é movido para a superior. Mas então, se eu pressionar C-jpara voltar à janela inferior, nada acontece.

Não sei se é a causa do problema, mas se eu tentar inserir um literalC-j em um buffer do Vim (pressionando C-v C-j), ^Mé exibido (a notação de acento circunflexo para um retorno de carro). Em uma instância regular do Vim (iniciada executando $ vim), inserir um literal C-jresulta em um caractere cuja notação de acento circunflexo é ^@(um NUL).

Eu posso reproduzir o problema com este mínimo ~/.zshrc:

export EDITOR=vim
autoload -Uz edit-command-line
zle -N edit-command-line
bindkey '^X^E' edit-command-line

E este mínimo ~/.vimrc:

nnoremap <c-j> :echom 'C-j has been pressed'<cr>

PressionandoC-x C-e na linha de comando zsh inicia o Vim e, em seguida, pressionar C-jdeve imprimir e registrar a mensagem:

C-j has been pressed

Mas nada acontece.

Não consigo reproduzir o problema no bash, nem com o Neovim ( v0.3.2-752-g4d7c7f9). Além disso, inserir um literal C-jno Vim, quando este foi iniciado a partir do bash após pressionar C-x C-e, resulta em um NUL ( ^@). A mesma coisa quando o Neovim é iniciado a partir do bash ou zsh após pressionar C-x C-e.

┌────────┬──────┬─────┐
│        │ bash │ zsh │
├────────┼──────┼─────┤
│ Vim    │ ^@   │ ^M  │
├────────┼──────┼─────┤
│ Neovim │ ^@   │ ^@  │
└────────┴──────┴─────┘

Eu pensei que talvez alguma opção de terminal do Vim não estivesse configurada corretamente, então capturei a saída de:

:set termcap

do Vim iniciado por $ vim, e do Vim iniciado por C-x C-e. Mas a saída é idêntica em ambos os casos:

--- Terminal codes ---

  t_AL=^[[%p1%dL      t_DL=^[[%p1%dM      t_mr=^[[7m          t_se=^[[27m         t_us=^[[4m
  t_al=^[[L           t_dl=^[[M           t_ms=y              t_Sf=               t_ut=
  t_bc=               t_EC=               t_nd=^[[C           t_SH=               t_vb=^[g
  t_BE=               t_EI=^[[2 q         t_op=^[[39;49m      t_SI=^[[6 q         t_vi=^[[?25l
  t_BD=               t_fs=^G             t_RF=               t_Si=               t_VS=
  t_cd=^[[J           t_GP=               t_RB=               t_so=^[[7m          t_vs=^[[34l
  t_ce=^[[K           t_IE=               t_RC=               t_SR=^[[4 q         t_WP=
  t_cl=^[[H^[[J       t_IS=               t_RI=^[[%p1%dC      t_sr=^[M            t_WS=
  t_Ce=               t_ke=^[[?1l^[>      t_Ri=               t_ST=               t_xn=y
  t_Co=256            t_ks=^[[?1h^[=      t_RS=               t_Te=               t_xs=
  t_CS=               t_le=^H             t_RT=               t_Ts=               t_ZH=^[[3m
  t_CV=               t_mb=^[[5m          t_RV=               t_ts=^[]0;          t_ZR=^[[23m
  t_da=               t_md=^[[1m          t_Sb=               t_u7=               t_8f=
  t_db=               t_me=^[[0m          t_SC=               t_ue=^[[24m         t_8b=
  t_AB=^[[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m
  t_AF=^[[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m
  t_cm=^[[%i%p1%d;%p2%dH
  t_Cs=^[]12;%p1%s^G
  t_cs=^[[%i%p1%d;%p2%dr
  t_te=^[[2 q^[[?1004l^[[?1049l
  t_ti=^[[2 q^[[?1004h^[[?1049h
  t_ve=^[[34h^[[?25h

--- Terminal keys ---

t_#2 <S-Home>    ^[[1;2H   t_k6 <F6>        ^[[17~    t_kh <Home>      ^[[1~          <ð>        ^[p
t_#4 <S-Left>    ^[[1;2D   t_k7 <F7>        ^[[18~    t_kl <Left>      ^[OD           <ô>        ^[t
t_%i <S-Right>   ^[[1;2C   t_k8 <F8>        ^[[19~    t_kr <Right>     ^[OC           <õ>        ^[u
t_*7 <S-End>     ^[[1;2F   t_k9 <F9>        ^[[20~    t_ku <Up>        ^[OA           <ù>        ^[y
t_@7 <End>       ^[[4~     t_k; <F10>       ^[[21~         <á>        ^[a            <ú>        ^[z
t_F1 <F11>       ^[[23~    t_kB <S-Tab>     ^[[Z           <â>        ^[b            <Mouse>     ^[[M
t_F2 <F12>       ^[[24~    t_kD <Del>       ^[[3~          <ä>        ^[d            <S-F18>     ^[[O
t_k1 <F1>        ^[OP      t_kI <Insert>    ^[[2~          <å>        ^[e            <S-F19>     ^[[I
t_k2 <F2>        ^[OQ      t_kN <PageDown>  ^[[6~          <æ>        ^[f            <xUp>       ^[[1;*A
t_k3 <F3>        ^[OR      t_kP <PageUp>    ^[[5~          <ç>        ^[g            <xDown>     ^[[1;*B
t_k4 <F4>        ^[OS      t_kb <BS>        ^?             <í>        ^[m            <xLeft>     ^[[1;*D
t_k5 <F5>        ^[[15~    t_kd <Down>      ^[OB           <î>        ^[n            <xRight>    ^[[1;*C

A saída de $ stty -atambém é idêntica em bash e zsh:

speed 38400 baud; rows 33; columns 119; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -ixon -ixoff
-iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc

estou a usarzsh 5.6.2-dev-1 (x86_64-pc-linux-gnu) .

Existe uma opção Vim ou zsh que deve ser definida para evitar que o Vim seja traduzido C-jquando C-miniciado pelo widget zle edit-command-line?

zsh vim
  • 1 respostas
  • 229 Views
Martin Hope
user938271
Asked: 2018-10-31 20:19:47 +0800 CST

Por que uma geração de nome de arquivo com falha faz com que o zsh pare de processar um script?

  • 6

Eu estava tentando escrever um pequeno script que escreveria todos os programas executáveis ​​encontrados em $PATH:

for dir in $(tr ':' ' ' <<<"${PATH}"); do
  for pgm in $dir/*; do
    if command -v "${pgm}" >/dev/null 2>&1; then
      echo "${pgm}"
    fi
  done
done | sort >file

No bash, funciona como esperado, mas o zsh para de processar o script assim que uma geração de nome de arquivo falha no loop interno:

for pgm in $dir/*; do
           ^^^^^^
  ...
done

Como resultado, como my $PATHcontém um diretório que não contém nenhum arquivo ( /usr/local/sbin), em zsh, o script falha ao gravar os executáveis ​​encontrados nos diretórios posteriormente.

Aqui está outro código mostrando o mesmo problema:

for f in /not_a_dir/*; do
  echo 'in the loop'
done
echo 'after the loop'

No bash, este comando gera:

in the loop
after the loop

E sai com o código 0.

Enquanto em zsh, o mesmo comando gera:

no matches found: /not_a_dir/*

E sai com o código 1.

A diferença de comportamento entre os shells parece vir da nomatchopção, que é descrita em man zshoptions:

NOMATCH (+3) <C> <Z>

Se um padrão para geração de nome de arquivo não tiver correspondências, imprima um erro, em vez de deixá-lo inalterado na lista de argumentos. Isso também se aplica à expansão de arquivo de um arquivo inicial ~ou =.

E também explicado em man zshexpn(seção GERAÇÃO DE NOME DE ARQUIVO):

A palavra é substituída por uma lista de nomes de arquivos classificados que correspondem ao padrão. Se nenhum padrão correspondente for encontrado, o shell fornecerá uma mensagem de erro, a menos que a opção NULL_GLOB seja definida, caso em que a palavra será excluída; ou a menos que a opção NOMATCH não esteja definida, caso em que a palavra permanece inalterada.

Porque se eu unset nomatch, zsh se comporta como bash:

unsetopt nomatch
for f in /not_a_dir/*; do
  echo 'in the loop'
done
echo 'after the loop'

Agora eu entendo a diferença de comportamentos entre bash e zsh e por que o script gera um erro em zsh, mas quero entender por que uma geração de nome de arquivo com falha faz com que o zsh pare imediatamente de processar um script. Então, tentei reproduzir o mesmo problema substituindo a geração de nome de arquivo com falha por um comando com falha (executando not_a_cmd):

for f in ~/*; do
  not_a_cmd
done
echo 'after the loop'

Mas a saída deste script é quase idêntica em ambos os shells (exceto pelas mensagens de erro devido a not_a_cmd). Em particular, ambos os shells imprimem:

after the loop

E ambos os shells saem com o código 0.

Por que uma geração de nome de arquivo com falha (como for f in /not_a_dir/*) faz com que o zsh pare de processar um script, mas não um comando com falha (como not_a_cmd)?

estou usando zsh 5.6.2-dev-0 (x86_64-pc-linux-gnu).

zsh
  • 1 respostas
  • 234 Views
Martin Hope
user938271
Asked: 2018-10-25 17:52:42 +0800 CST

Como fazer o zsh passar a seção manual para o comando man quando o estilo `separate-sections` está definido?

  • 4

Ao solicitar uma conclusão pressionando Tab na linha de comando zsh, as correspondências podem ser agrupadas de acordo com sua tag, desde que o group-nameestilo seja definido como uma string vazia:

autoload -Uz compinit
compinit
zstyle ':completion:*' menu select
zstyle ':completion:*' group-name ''
zstyle ':completion:*:descriptions' format '%d'

No caso do $ mancomando, as correspondências podem ser divididas ainda mais se o separate-sectionsestilo for definido como truepara a manualstag:

autoload -Uz compinit
compinit
zstyle ':completion:*' menu select
zstyle ':completion:*' group-name ''
zstyle ':completion:*:descriptions' format '%d'
zstyle ':completion:*:manuals' separate-sections true

Como resultado, se eu pressionar Tab após $ man write, o sistema de conclusão sugere estas correspondências:

$ man write
manual page, section 1 (general commands)
write
manual page, section 2 (system calls)
write   writev

E se eu selecionar a writecorrespondência na primeira lista, $ manabre a writepágina na primeira seção do manual.

Mas se eu selecionar a writecorrespondência na segunda lista, $ manainda abre a writepágina na primeira seção, enquanto a descrição da lista menciona a segunda seção do manual.

É possível fazer o zsh passar a seção do manual relevante para o comando man quando o separate-sectionsestilo é definido?

estou usando zsh 5.6.2-dev-0 (x86_64-pc-linux-gnu).

zsh autocomplete
  • 1 respostas
  • 512 Views
Martin Hope
user938271
Asked: 2018-10-23 08:35:25 +0800 CST

Como pesquisar um padrão contendo hífens dentro de páginas de manual?

  • 11

Estou tentando encontrar um comando para procurar um padrão contendo hífens dentro de todas as páginas man.

Pesquisei man mane encontrei essas 3 opções:

-K,--global-apropos

Procure texto em todas as páginas do manual. Esta é uma busca de força bruta e provavelmente levará algum tempo; se puder, especifique uma seção para reduzir o número de páginas que precisam ser pesquisadas. Os termos de pesquisa podem ser strings simples (o padrão) ou expressões regulares se a --regexopção for usada.

-w, --where, --path,--location

Na verdade, não exiba as páginas de manual, mas imprima os locais dos arquivos nroff de origem que seriam formatados.

-S list, -s list,t--sections=list

Lista é uma lista separada por dois pontos ou vírgulas de seções manuais específicas de pedidos a serem pesquisadas. Esta opção substitui a $MANSECTvariável de ambiente. (A -sortografia é para compatibilidade com o System V.)

Eu tentei combiná-los para procurar o padrão mark-modified-linesque é uma opção de linha de leitura descrita em man bash:

$ man -s1 -Kw mark-modified-lines

Mas não encontra nenhuma página:

No manual entry for mark-modified-lines

E o comando sai com o código 16.
Eu pensei que talvez a sintaxe do comando estivesse errada, mas não parece, já que este comando encontra corretamente as 5 páginas man no meu sistema que contém a palavra guitar:

$ man -s1 -Kw guitar

  /usr/share/man/man1/ffmpeg-all.1.gz
  /usr/share/man/man1/ffserver-all.1.gz
  /usr/share/man/man1/ffplay-all.1.gz
  /usr/share/man/man1/ffmpeg-filters.1.gz
  /usr/share/man/man1/ffprobe-all.1.gz

Eu pensei que talvez os hífens na palavra causassem um problema. Em man bash, encontrei a --regexopção descrita a seguir:

--regex

Mostre todas as páginas com qualquer parte de seus nomes ou descrições que correspondam a cada argumento de página como uma expressão regular, como em apropos(1). Como geralmente não há uma maneira razoável de escolher uma "melhor" página ao pesquisar uma expressão regular, essa opção implica -a.

Tentei usar esta opção e substituir a palavra mark-modified-linespelo regex mark.modified.lines, onde os próprios hífens são substituídos pelo metacaractere .que deve corresponder a qualquer caractere:

$ man -s1 -Kw --regex 'mark.modified.lines'

Ele ainda não imprime nenhuma página, embora eu saiba que o texto está escrito na bashpágina man.

O metacaractere .no regex parece ser analisado conforme o esperado, pois este comando:

$ man -s1 -Kw --regex 'mark.mo'

Impressões:

  /usr/share/man/man1/x11perfcomp.1.gz
  /usr/share/man/man1/xditview.1.gz

E essas 2 manpages ( x11perfcomp, xditview) são correspondidas pela regex mark.mo. Mais especificamente, man x11perfcompcontém esta linha:

Mark Moraes wrote the original scripts to compare servers.
^^^^^^^

E man xditviewcontém esta linha:

    Mark Moraes (University of Toronto)
    ^^^^^^^

No entanto, man -s1 -Kw --regex 'mark.mo'não imprime a página de manual do bash:

/usr/share/man/man1/bash.1.gz

Enquanto eu esperava que sim, pois contém esta linha:

mark-modified-lines (Off)
^^^^^^^

É possível procurar um padrão contendo hífens dentro das páginas man?

man
  • 1 respostas
  • 997 Views
Martin Hope
user938271
Asked: 2018-09-24 14:57:31 +0800 CST

Como imprimir todos os atributos de um parâmetro zsh?

  • 4

Eu posso dar o -Uatributo para um array não associativo para que ele não contenha elementos duplicados:

% declare -U path
% path=( ~/bin $path )
% path=( ~/bin $path )
% echo $path

Aqui, embora eu tenha adicionado ~/binao array pathduas vezes, o último contém apenas um ~/binelemento.

Estou procurando uma maneira de imprimir todos os atributos que podem ser dados a um parâmetro durante uma atribuição, incluindo esse -Uatributo.

Eu olhei para o typesetcomando em man zshbuiltins, e encontrei este trecho:

Exceto quando as atribuições são feitas com nome=valor, usar +m força os parâmetros correspondentes e seus atributos a serem impressos, mesmo dentro de uma função.

Então, eu tentei executar estes comandos:

% declare -U path
% declare +m 'path'

Cuja saída é:

array path

Enquanto ele me diz o tipo do parâmetro (aqui um array), ele não me diz que tem o -Uatributo.

Existe outro comando que imprimiria todos os atributos de um parâmetro?

zsh
  • 1 respostas
  • 358 Views
Martin Hope
user938271
Asked: 2018-09-15 11:18:08 +0800 CST

Como definir o número da versão informada por `$ tmux -V`, durante a compilação de um pacote `tmux`?

  • 0

Estou compilando o tmux a partir de seu código-fonte por meio de um script que se parece com isso:

set -e
DIR="${HOME}/Programs/"
build() {
  [[ -d "${DIR}" ]] || mkdir -p "${DIR}"
  cd "${DIR}"
  if [[ ! -d tmux ]]; then
    git clone https://github.com/tmux/tmux
  fi
  cd tmux
  git stash
  git checkout master
  git pull
  make clean; make distclean
  sh autogen.sh
  ./configure
  make
}
install() {
  dpkg -r tmux
  checkinstall --pkgname tmux --pkgversion '9999:9999.9999' -y
}
build
install

Ele compila e instala o tmux, conforme o esperado.
Mas ainda há um problema, que é a versão relatada por $ tmux -V:

$ tmux -V
tmux master

Ele relata tmux master, enquanto eu preferiria tmux X.Y, X.Yser a versão mais recente. Por exemplo, no momento, a versão mais recente é 2.8, então gostaria $ tmux -Vde produzir tmux 2.8.

Existe alguma maneira de alterar essa saída?

Examinei a saída de ./configure --helpe procurei uma opção para definir a versão do processo tmux, mas não consegui encontrar uma.

No momento, incluí um sedcomando no meu script para que ele edite automaticamente o arquivo configure.ace atribua um grande número de versão 99.99(não sei como obter programaticamente o número da versão mais recente):

sh autogen.sh
sed -i 's/AC_INIT(tmux, master)/AC_INIT(tmux, 99.99)/' configure.ac
./configure

Existe uma maneira melhor?


A razão pela qual faço essa pergunta é porque uso o plugin tmux-open , que não funciona como esperado quando $ tmux -Voutputs tmux master.

O último usa esta linha de código para determinar a versão do processo tmux atual:

$ tmux_version="$(tmux -V | cut -d ' ' -f 2)"

O plug-in então usa essa variável para determinar a sintaxe dos comandos que instalam os atalhos de teclado .

As associações de teclas não estão instaladas na minha máquina e acho que é devido à saída do $ tmux -V. Porque se eu substituir essa linha no plugin:

if [[ $tmux_version == $1 ]]

com esta linha:

if [[ $tmux_version == $1 ]] || [[ $tmux_version == 'master' ]]

Em seguida, o plug-in instala corretamente suas combinações de teclas.

tmux
  • 1 respostas
  • 166 Views
Martin Hope
user938271
Asked: 2018-05-21 18:06:20 +0800 CST

Como iniciar o Vim a partir de uma armadilha e ainda poder retomá-lo após suspendê-lo?

  • 2

Eu tenho o seguinte código no meu ~/.zshrc:

nv() (
  if vim --serverlist | grep -q VIM; then
    if [[ $# -eq 0 ]]; then
      vim
    elif [[ $1 == -b ]]; then
      shift 1
      IFS=' '
      vim --remote "$@"
      vim --remote-send ":argdo setl binary ft=xxd<cr>"
      vim --remote-send ":argdo %!xxd<cr><cr>"
    elif [[ $1 == -d ]]; then
      shift 1
      IFS=' '
      vim --remote-send ":tabnew<cr>"
      vim --remote "$@"
      vim --remote-send ":argdo vsplit<cr>:q<cr>"
      vim --remote-send ":windo diffthis<cr>"
    elif [[ $1 == -o ]]; then
      shift 1
      IFS=' '
      vim --remote "$@"
      vim --remote-send ":argdo split<cr>:q<cr><cr>"
    elif [[ $1 == -O ]]; then
      shift 1
      IFS=' '
      vim --remote "$@"
      vim --remote-send ":argdo vsplit<cr>:q<cr><cr>"
    elif [[ $1 == -p ]]; then
      shift 1
      IFS=' '
      vim --remote "$@"
      vim --remote-send ":argdo tabedit<cr>:q<cr>"
    elif [[ $1 == -q ]]; then
      shift 1
      IFS=' '
      vim --remote-send ":cexpr system('$*')<cr>"
    else
      vim --remote "$@"
    fi
  else
    vim -w /tmp/.vimkeys --servername VIM "$@"
  fi
)

Sua finalidade é instalar uma nvfunção para iniciar uma instância do Vim, bem como um servidor Vim. E se um servidor Vim já estiver em execução, a função deve enviar os argumentos de arquivo recebidos para o servidor.

Até agora, funcionou bem.


Eu tenho o seguinte mapeamento no meu ~/.vimrc:

nno  <silent><unique>  <space>R  :<c-u>sil call <sid>vim_quit_reload()<cr>
fu! s:vim_quit_reload() abort
    sil! update
    call system('kill -USR1 $(ps -p $(ps -p $$ -o ppid=) -o ppid=)')
    qa!
endfu

Sua finalidade é reiniciar o Vim, enviando o sinal USR1para o shell pai.

Eu também tenho a seguinte armadilha no meu ~/.zshrcque reinicia o Vim quando ele pega o sinal USR1.

catch_signal_usr1() {
  trap catch_signal_usr1 USR1
  clear
  vim
}
trap catch_signal_usr1 USR1

Até agora, funcionou bem também.


Mas notei que, se eu suspender o Vim pressionando C-z, no shell, mesmo que o processo do Vim ainda esteja em execução, não consigo retomá-lo (com $ fg) porque o shell não tem nenhum trabalho.

Aqui está um mínimo zshrccom o qual posso reproduzir o problema:

catch_signal_usr1() {
  trap catch_signal_usr1 USR1
  vim
}
trap catch_signal_usr1 USR1
func() {
  vim
}

E aqui vai um mínimo vimrc:

nnoremap  <space>R  :call Func()<cr>
function! Func()
    call system('kill -USR1 $(ps -p $(ps -p $$ -o ppid=) -o ppid=)')
    qa!
endfunction

Se eu iniciar o Vim com a função:

$ func

Em seguida, reinicie o Vim pressionando Space R, em seguida, suspenda-o pressionando C-z, quando voltar ao shell, posso ver o processo do Vim em execução:

$ ps -efH | grep vim
user     24803 24684 10 03:56 pts/9    00:00:01             vim
user     24990 24684  0 03:56 pts/9    00:00:00             grep vim

Mas não consigo resumir:

$ fg
fg: no current job

Se eu iniciar o Vim com o $ vimcomando em vez da $ funcfunção, posso reiniciar o processo do Vim, suspendê-lo e retomá-lo. O problema parece vir da função $ func.


Aqui está o meu ambiente:

  • vim --version: VIM - Vi IMproved 8.1 Compilado pelo usuário
  • Sistema operacional: Ubuntu 16.04.4 LTS
  • Emulador de terminal: rxvt-unicode v9.22
  • Multiplexador de terminal: tmux 2.7
  • $TERM: tmux-256color
  • Shell: zsh 5.5.1

Como iniciar o Vim a partir de uma função e ainda poder retomá-lo após suspendê-lo?


Editar:

Mais Informações:

(1) O que aparece no seu terminal quando você digita Ctrl+Z?

Nada é exibido quando eu digito C-z.

(A) Se eu iniciar o Vim com o $ vimcomando, aqui está o que é exibido depois de pressionar C-z:

ubuntu% vim

zsh: suspended  vim

Posso retomar com $ fg.


(B) Se eu iniciar o Vim com a $ funcfunção:

ubuntu% func
zsh: suspended  func

Eu também posso retomar com $ fg.


(C) Se eu iniciar o Vim com o $ vimcomando, reinicie o Vim pressionando Space R:

ubuntu% vim
zsh: suspended  catch_signal_usr1

Mais uma vez, posso continuar com $ fg.


(D) Mas, se eu iniciar o Vim com a $ funcfunção e reiniciá-lo pressionando Space R:

ubuntu% func
ubuntu%

Nada é exibido quando volto ao prompt e não consigo retomar o Vim com $ fg.


(2) O que seu shell diz se você digitar jobs?

$ jobsnão tem saída. Aqui está sua saída nos quatro casos anteriores:

(UMA)

ubuntu% jobs
[1]  + suspended  vim

(B)

ubuntu% jobs
[1]  + suspended (signal)  func

(C)

ubuntu% jobs
[1]  + suspended (signal)  catch_signal_usr1

(D)

ubuntu% jobs
ubuntu%

Parece que o problema é específico de zshpelo menos até 5.5.1, pois não consigo reproduzir com bash 4.4.

zsh vim
  • 1 respostas
  • 580 Views

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

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