Comece todos os comandos com uma vírgula (2009)
(rhodesmill.org)- Quando usuários Unix colocam scripts pessoais em
~/bin/e os adicionam aoPATH, nomes curtos de comandos podem entrar em conflito com novos comandos do sistema - Em ambientes com muitos comandos fornecidos, como Debian/Ubuntu, o risco aumenta; no notebook Ubuntu do exemplo, foram contabilizados 21.733 comandos em
/usr/bin - Colocar uma vírgula (
,) antes dos comandos pessoais faz com que o shell e as ferramentas a tratem como um caractere comum de nome de arquivo, ao mesmo tempo em que a distingue facilmente dos comandos do sistema - A vírgula pode ser digitada sem Shift e tem menos chance de causar conflitos do que parênteses, barra invertida, dois-pontos, crase, apóstrofo, barra e ponto, que têm significados fortes no shell
- Ao pressionar Tab depois de
,, é possível percorrer imediatamente a lista de comandos pessoais, facilitando manter os nomes dos comandos em~/bin/bem organizados
Por que nomes de comandos pessoais entram em conflito
- Muitos usuários Unix criam
~/bin/no diretório home e o adicionam aoPATHpara usar comandos utilitários pessoais e scripts de shell - O problema é que os nomes dos scripts pessoais costumam ser combinações curtas de letras minúsculas, o que os torna fáceis de se parecerem com comandos básicos do sistema
- Quando uma distribuição Linux adiciona um novo comando, ele pode acabar tendo por acaso o mesmo nome de um comando pessoal existente
- Em ambientes da família Debian, o grande número de comandos fornecidos torna esse problema mais realista
- No notebook Ubuntu do exemplo, contar os comandos diretamente sob
/usr/binresulta em21.733 apt-file search -x '^/usr/bin/[^/]*$' | wc -l
- No notebook Ubuntu do exemplo, contar os comandos diretamente sob
Vantagens do prefixo com vírgula
- A solução é mudar os nomes dos comandos pessoais para uma forma que seja fácil de digitar, mas improvável de ser escolhida como nome de comando do sistema
- O critério de conveniência de digitação é não usar a tecla Shift, e não há muitos caracteres seguros que satisfaçam essa condição
- Letras minúsculas já são usadas com frequência em comandos do sistema
- Parênteses, barra invertida, dois-pontos, crase e apóstrofo têm significados especiais no shell
- A barra é separador de diretórios, portanto não pode fazer parte de um nome de arquivo
- O ponto, no início de um nome de arquivo, indica arquivo oculto; em outras posições, também é usado com frequência para separar extensões
- A opção que sobra é a simples vírgula (
,), e as ferramentas ao redor e o shell tratam a vírgula como um caractere comum dentro do nome de arquivo - Ao adicionar a vírgula como prefixo a cada comando pessoal, eles ficam claramente separados dos comandos do sistema, facilitando evitar colisões de nome
- Usada com autocompletar por Tab, permite ver imediatamente a lista de comandos pessoais depois de digitar
,- A lista de exemplo inclui
,complete-scp,,complete-ssh,,coreoff,,coreon,,find,,go-thpgp,,gr,,hss,,mount-thpgp,,mount-twt,,range,,svn-store-password,,umount, entre outros
- A lista de exemplo inclui
- Essa abordagem vem sendo usada há cerca de 10 anos e é recomendada como uma forma de manter bem organizados os nomes de comandos pessoais em
~/bin/
2 comentários
Comentários no Hacker News
Só pelo título, achei que seria uma ideia horrível, mas na prática gostei bastante. Gostei especialmente da parte de listar todas as minhas ferramentas com Tab
Ultimamente não tenho sofrido muito com colisões de namespace, e também é verdade que, depois que migrei para gestão, meu senso técnico ficou meio enferrujado. Meu stack técnico parece estar uns 10 anos defasado, e fico me perguntando por onde seria bom começar para voltar a acompanhar o que há de mais atual
O que eu faço é criar ferramentas que facilitem minha própria vida. Por exemplo, se há um serviço web na empresa que eu uso com frequência para consultas simples, procuro ver se existe uma API e escrevo uma CLI para acelerar as tarefas do dia a dia. Depois de deixá-la do jeito que gosto, compartilho com a equipe, mas é difícil convencer outras pessoas a experimentarem. Ainda assim, como eu uso todos os dias, não me preocupo muito com isso
O objetivo era enxergar novas perspectivas e conseguir conversar sobre tendências, e parte disso agora acabou chegando ao trabalho. Isso também me ajudou a entender melhor os componentes mais antigos
Não entendo muito bem esse problema. Basta colocar meu diretório
binno começo do$PATH, não no fim. Para ver meus comandos, simplesmente rodols ~/bin$0esteja em um caminho do sistema, isso quebrar, e começar uma depuração frustranteNo fim, é uma questão de escolher qual veneno tomar
fzf. Por exemplo, no fish, dá para digitar a primeira letra de um comando e apertar Tab para abrir ofzfAssim, só com
,+Tab você consegue filtrar rapidamente os comandos personalizados. Jáls ~/binexige digitar bastante para algo feito com frequência; ou então talvez seja preciso procurar primeiro no histórico/autocompletação comls+seta para cima várias vezesls ~/biné muito mais lento de digitar do que,Eu uso nomes curtos de comandos personalizados, como
aa,st,di,dp,cm,le, para wrappers finos em torno dogitUm deles realmente entra em conflito com um utilitário instalado por padrão em algum sistema. Mesmo assim, como meu diretório
binvem antes dos diretórios do sistema no$PATH, o meu ganha, e não tenho muito interesse nessa ferramenta conflitante. Se alguma outra ferramenta útil para mim conflitasse com a minha, eu provavelmente criaria para essa outra ferramenta um alias que não conflitasse, em vez de renomear a minha. Essas ferramentas de duas letras são convenientes demaisapt-get upgradeexecutar Dwarf Fortresshttps://askubuntu.com/questions/938606/dwarf-fortress-starti...
gitgeralmente são combinações de duas letras começando comg. Por exemplo,gségit statusSó que às vezes eu realmente preciso do GhostScript. Ele é excelente para casos como incorporar fontes em arquivos PDF. Normalmente, nessas horas, uso
env gsj. Quandojavaapareceu, isso ficou bem divertido. Usar vírgula é uma ideia bem interessanteAinda bem que não comecei com
k, por causa do KDE :)Por exemplo, acho que
mkfsdeveria ser chamado comosys::mkfs. A linha que separa comandos do sistema e comandos do usuário pode ser definida de várias maneiras, e haverá partes ambíguas, mas se o usuário pode executar por engano um comando que nem sabe que existe e que nunca instalou explicitamente, então esse comando não deveria ficar exposto diretamente no namespace globalHá uma pergunta relacionada
Eu uso Windows na maior parte do tempo e, como o autor, criei vários scripts de CLI centrados em Python e os coloco no equivalente a
~/bin/. Se eu definirpython.execomo o programa padrão para a extensão.pye adicionar.pyao%pathext%, consigo executar~/bin/hello.pydigitando apenashellode qualquer diretório, e uso isso centenas de vezes por dia. Hoje em dia uso mais Linux, mas ainda sou iniciante e não consegui fazer do mesmo jeito. No Linux parece não existir o conceito de “programa associado”, então não dá para simplesmente chamar um arquivo.pye fazer o shell executá-lo com Python. Claro, posso darchmod +xno script, mas aí preciso colocar um shebang no próprio script, o que me incomoda por parecer hardcoded. E se no futuro eu quiser executar scripts.pycom/usr/bin/nohtypem vez de/usr/bin/python? Além disso, também não encontrei uma forma de omitir a parte.pyao chamar o script. Não quero criticar o design do Linux, e sei que ele tem muitas vantagens, mas eu realmente quero executarhello.pyque está no$PATHcomohellomy_pythonem algum diretório do caminho e use o shebang/usr/bin/env my_pythonSe quiser uma abordagem mais principiada, veja a ferramenta
update-alternatives. Ela oferece esse tipo de abstração de forma mais geral: https://linuxconfig.org/how-to-set-default-programs-using-up...No Linux — na verdade, na maioria das plataformas fora o Windows — o significado das extensões de arquivo é muito mais fraco. Para qualquer tipo de executável, o que determina se ele pode ser executado não é a extensão, e sim coisas como a flag
+x. Isso permite reescrever algo em outra linguagem de implementação sem quebrar quem chama. A extensão.pysó faz sentido para módulos importados e usados; se for um script executável, quando necessário você olha o shebang. Scripts distribuídos externamente normalmente usam#!/usr/bin/env python, e scripts incluídos em pacotes da distribuição acabam sendo sobrescritos com algo como#!/usr/bin/python. Além disso, o shebang não dá suporte a vários argumentos, mas oenvdo GNU oferece a opção-S, que consegue simular isso. Ainda resta, porém, o problema do tamanho dos argumentos.pydo nome do arquivo. Chamá-lo de"hello"é perfeitamente aceitávelNão consigo pensar em grandes desvantagens do shebang. Se você realmente quiser executar com outro interpretador, explicite como
"nohtyp hello". Se ainda assim isso incomodar muito, você pode definir um alias no arquivo de inicialização do shell. Por exemplo, no bash dá para fazeralias hello="python3 /path/to/hello.py". Se quiser, também dá para escrever um script curto que gere automaticamente aliases desse tipo para o conteúdo de um diretório específicoEm scripts de shell, normalmente você adiciona um shebang e torna o arquivo executável, declarando o executável no próprio script. Pense no shebang como uma espécie de extensão de arquivo. Se
./malware.pynão funcionar depois dechmod +x ./malware.py, verifique o caminho apontado pelo shebang. Se o interpretador consegue executar o script como um argumento comum, dá para obter um comportamento parecido com algo comoxdg-open malware.py. Seria equivalente a dar duplo clique no gerenciador de arquivos padrão. Quando eu usava Linux como sistema operacional principal no desktop, tive um alias chamadoxop, mas só o usava para arquivos de dados, como imagens ou documentos, cujo comportamento padrão já estava correto. Não recomendo definir o programa padrão de scripts executáveis como o interpretador. Por padrão, talvez você queira abrir scripts em um editor, e não executá-los. Acho quexdg-opené uma ferramenta do lado do Gnome, mas isso não quer dizer que não possa ser usada em outros desktops; eu também a usava no Xubuntu. Se você realmente quiser executar por padrão todos os arquivos Python também no contexto da GUI, dá para configurar esse padrão, masman xdg-openpode ajudar. Reforçando: não é um bom conselho#!/usr/bin/env pythonAssim, o primeiro
pythonencontrado no caminho será executado. Se no futuro você quiser executar com/usr/bin/nohtypem vez de/usr/bin/python, pode criar um link simbólico chamadopythonapontando para/usr/bin/nohtypem um diretório pesquisado antes de/usr/bin. Por exemplo, adicione~/myCommandPreferencesao início do$PATHOutra forma de evitar conflitos no
$PATHé criar nomes de executáveis bem longos, com pouca chance de serem usados por outros executáveis, e colocar aliases curtos nobashrcAliases não afetam executáveis chamados dentro de scripts, e nos meus scripts eu posso continuar referenciando os nomes longos. A desvantagem é que você não obtém o mesmo nível de usabilidade com autocompletar por Tab, embora essa parte seja realmente muito boa. Além disso, ainda pode haver conflitos em scripts que precisam ser executados com
source, e não como subprocessos, como o script de ativação devenvdo Python, mas esses casos são raroszsh, esse autocompletar também funcionaComeçar com vírgula é uma técnica comum também na comunidade de expansores de texto/substituição de texto
,Recentemente, ao dar uma olhada em
~/.local/bin/, descobri dezenas de executáveis que não me lembrava de ter colocado aliA maioria era relacionada ao pyside, mas havia outros scripts também. Tive que abrir um por um para lembrar quais scripts eu mesmo tinha escrito e quais tinham sido criados por outras pessoas. Se os nomes dos meus scripts começassem com vírgula, teria sido muito mais rápido, e isso também teria ajudado a lembrar, antes de abrir cada script, por que eu o tinha criado
~/.local/bin/é para scripts instalados, e o que você escreve localmente fica em~/bin/Passo. Basta colocar meu
binpessoal antes no$PATHe usar/usr/binou/binquando precisar referenciar programas encobertosA lista de ferramentas personalizadas pode ser exibida com
~/bin/[Tab]Se eu não gosto do
grepdo sistema, por exemplo ogrepdo Solaris, e quero usar o GNUgrepque prefiro, por que simplesmente não deixá-lo comogrep?Ter encontrado essa ideia há 5 anos me ajudou a colocar ordem no meu conjunto de truques de shell. Entre aliases e
~/bin, tenho mais de 50 comandos com vírgula, e minha vida no shell ficou muito mais fluida do que naquela bagunça de antesTambém foi discutido em 2020: https://news.ycombinator.com/item?id=22778988 (90 comentários)
, macroexpandStart all of your commands with a comma (2009) - https://news.ycombinator.com/item?id=31846902 - junho de 2022 (121 comentários)
Start all of your commands with a comma (2009) - https://news.ycombinator.com/item?id=22778988 - abril de 2020 (89 comentários)
Que tal usar
'_'?