Compartilhe as suas alias e funções - facilitando o dia a dia

Eu uso muito alias e funções no bash/zsh que facilita o dia a dia.
Estou criando este tópico para quem quiser compartilhar as suas alias

# Colorir páginas de manuais
export LESS_TERMCAP_mb=$(printf '\e[01;31m') # Entrar no modo intermitente - vermelho
export LESS_TERMCAP_md=$(printf '\e[01;35m') # Entrar no modo de duplo brilho - negrito, magenta
export LESS_TERMCAP_me=$(printf '\e[0m') # Desativar todos os modos de aparência (mb, md, so, us)
export LESS_TERMCAP_se=$(printf '\e[0m') # Deixar o modo standout
export LESS_TERMCAP_so=$(printf '\e[01;33m') # Entrar no modo standout - amarelo
export LESS_TERMCAP_ue=$(printf '\e[0m') # Deixar o modo sublinhado
export LESS_TERMCAP_us=$(printf '\e[04;36m') # Entrar no modo sublinhado - ciano

Para quem usa opensuse

# openSUSE
alias atualizar='sudo zypper dup'
alias remover='sudo zypper remove --clean-deps'
#alias remover='sudo zypper remove'
alias instalar='sudo zypper install'
alias procurar='zypper search --installed-only'
alias pesquisar='sudo zypper search'
alias orfaos='zypper pa --orphaned'
alias remove-orfaos='sudo zypper rm -u'
desnecessario(){
zypper packages --unneeded|awk -F '|' '{print $3}'| tail -n  +5
}
# Listar arquivos de hoje
alias lshoje='ls -al --time-style=+%D | grep `date +%D`'

# Lista grupos
alias grupos='cut -d: -f1 /etc/group'

# otimizar pdf
alias otimizarpdf='ps2pdf -dPDFSETTINGS=/ebook'

# Mostrar permissão
alias permissão='stat -c "(%F)- %n %a %A" "$@"'

# Mostrar as montagens por coluna
alias cmount="mount | column -t"

# Mostrar portas abertas/ativas tcp e udp
alias portas='netstat -tulanp'


Funções

# Lista unidades do systemd
listar-arquivos-unit(){
[[ "$1" == "s" && "$#" -lt 2 ]] && systemctl list-unit-files;
[[ "$1" == "u" && "$#" -lt 2 ]] && systemctl list-unit-files --user;
[[ "$1" == "sm" && "$#" -lt 2 ]] && systemctl list-unit-files --state masked;
[[ "$1" == "um" && "$#" -lt 2 ]] && systemctl --user list-unit-files --state masked;
[[ "$1" == "se" && "$#" -lt 2 ]] && systemctl list-unit-files --state=enabled;
[[ "$1" == "sd" && "$#" -lt 2 ]] && systemctl list-unit-files --state=disabled;
[[ "$1" == "ss" && "$#" -lt 2 ]] && systemctl list-unit-files --state=static;
[[ "$1" == "ue" && "$#" -lt 2 ]] && systemctl --user list-unit-files --state=enabled;
[[ "$1" == "ud" && "$#" -lt 2 ]] && systemctl --user list-unit-files --state=disabled;
[[ "$1" == "us" && "$#" -lt 2 ]] && systemctl --user list-unit-files --state=static;
if [[ "$#" -eq 0 || "$1" != "s" && "$1" != "u"  && "$1" != "sm" && "$1" != "um"  && "$1" != "se" && "$1" != "sd" && "$1" != "ss" && "$1" != "u" && "$1" != "ue" && "$1" != "ud"  && "$1" != "us" ]]; then
cat << USOAJUDA
$@ não é uma opção válida.

ajuda: listar-arquivos-unit [opções]
  s     : Mostra os arquivos unit do sistema
  u     : Mostra os arquivos unit do usuário
  sm    : Mostra os arquivos unit do sistema mascaradas
  um    : Mostra os arquivos unit do usuário mascaradas 
  se	: Mostra os arquivos unit do sistema habilitados
  sd	: Mostra os arquivos unit do sistema desativados
  ss    : Mostra os arquivos unit do sistema estáticos
  ue    : Mostra os arquivos unit do usuário habilitados
  ud	: Mostra os arquivos unit do usuário desativados
  us	: Mostra os arquivos unit do usuário estáticos
USOAJUDA
fi
}

# Lista usuários
usuarios(){
[[ "$1" == "r" && "$#" -lt 2 ]] && awk -F : '$3 < 1 || $3 >= 1000 { print $1}' /etc/passwd;
[[ "$1" == "c" && "$#" -lt 2 ]] && awk -F : '$3 >= 1000 { print $1}' /etc/passwd;
[[ "$1" == "s" && "$#" -lt 2 ]] && awk -F : '$3 > 0 && $3 < 1000 { print $1}' /etc/passwd;
[[ "$1" == "S" && "$#" -lt 2 ]] && sudo pdbedit -L  | cut -d \: -f1;
if [[ "$#" -eq 0 ]]; then
  cut -d \: -f1 /etc/passwd;
elif [[ "$#" -gt 1 || "$1" != "c" && "$1" != "r" && "$1" != "s" && "$1" != "S" ]]; then
cat << USOAJUDA
$@ não é uma opção válida.

ajuda: usuarios [opções]
  r     : Mostra com o usuário root
  c     : Mostra usuários criados sem o serviços
  s	: Mostra usuários de serviços
  S	: Mostra usuários do samba

Exemplo:
usuarios r
usuarios
USOAJUDA
fi
}

# Históricos mais usados
maisusados(){
  history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10
}

# Color Console
if [ "$TERM" = "linux" ]; then
    _SEDCMD='s/.*\*color\([0-9]\{1,\}\).*#\([0-9a-fA-F]\{6\}\).*/\1 \2/p'
    for i in $(sed -n "$_SEDCMD" $HOME/.Xresources | awk '$1 < 16 {printf "\\e]P%X%s", $1, $2}'); do
        echo -en "$i"
    done
    clear
fi


# Subir pastas
subir() {
local d=""
limit=$1
 for ((i=1 ; i <= limit ; i++)); do
   d=$d/..
 done
 d=$(echo $d | sed 's/^\///')
 if [[ -z "$d" ]]; then
  d=..
 fi
 cd $d
}

Tem mais, depois adiciono.

EDITADO
Para usuários do Arch utilizava bastante

# Remover arquivos orfãos
limpar_orfaos() {
declare ORPHAN=$(pacman -Qdtq)
 [ "$UID" != 0 ] && SU=sudo
 [ -z "$ORPHAN" ] && echo "não há nada a fazer" || $SU pacman -Rsn ${ORPHAN}
}

Um mais completo

    # Remover arquivos órfãos
    limpar_orfaos() {
    declare ORPHAN=$(pacman -Qdtq)
     [ "$UID" != 0 ] && SU=sudo
     echo 'Verificando orfãos com pacman'
     [ -z "$ORPHAN" ] && echo "não há pacotes órfãos" || $SU pacman -Rsn ${ORPHAN}
     echo 'Verificando cache de pacotes'
     paccache -rvuk0 | sed -e 's/no candidate packages found for pruning/nenhum pacote encontrado para ser removido/g' -e 's/finished:/concluído:/g' -e 's/packages removed/pacotes removidos/g' -e 's/disk space saved/espaço em disco salvo/g'

    }
1 Curtida

Pouco menos de uma semana atrás eu tinha feito justamente isso

1 Curtida

ok…

eu tinha procurado por alias e não nada…

depois adiciono lá.

Não tenho muitos alias/funções:

alias suvi='sudo -E nvim'
alias condaInit='source ~/.local/share/.conda_init'
alias condaClose='conda deactivate'

Para base Debian, sempre levo os:

alias rem="sudo apt remove --purge"
alias ins="sudo apt install"
alias pes="apt search"
alias lim="sudo apt autoclean; sudo apt autoremove"
1 Curtida

Olá @swatquest,
As suas função poderiam ser mais simples, para ajudar você e quem estiver começando com shell script, irei explicar:

É bem comum ver quem não tem muita experiência com scripting ou programação ficar repetindo métodos de checagem para executar uma ação. Entanto isto só é recomendado para casos muito complexos/específicos.

Exemplo:

Aqui você queira que múltiplas ações fossem executadas no caso de a variável $# ser menor que 2 e de a variável $1 for igual a uma string, você poderia ter feito de forma a utilizar apenas um if e um case, mostrarei em codigo:

if [ "$#" -lt 2 ]; then
    case "$1" in
        "r") awk -F : '$3 < 1 || $3 >= 1000 { print $1}' /etc/passwd;;
        # Outras opções...
        *) echo "Opção '$1' invalida.";;
    esac
fi

Desta forma é muito melhor para ler e ainda mais logicamente falando, se você quer verificar as opções na condição de ter passado apenas um argumento é melhor verificar se $# é igual a 1.

Alterei algumas de suas funções para exemplo:
# Lista unidades do systemd
lsau(){
    hmsg012391299TMP="\n'$@' não é uma opção válida.\n\nAjuda: listar-arquivos-unit [OPÇÂO]\n s     : Mostra os arquivos unit do sistema\n u     : Mostra os arquivos unit do usuário\n sm    : Mostra os arquivos unit do sistema mascaradas\n um    : Mostra os arquivos unit do usuário mascaradas\n se	: Mostra os arquivos unit do sistema habilitados\n sd	: Mostra os arquivos unit do sistema desativados\n ss    : Mostra os arquivos unit do sistema estáticos\n ue    : Mostra os arquivos unit do usuário habilitados\n ud	: Mostra os arquivos unit do usuário desativados\n us	: Mostra os arquivos unit do usuário estáticos\n"

    if [ "$#" -eq 1 ]; then
        case "$1" in
            "s" ) systemctl list-unit-files;;
            "u" ) systemctl list-unit-files --user;;
            "sm" ) systemctl list-unit-files --state masked;;
            "um" ) systemctl --user list-unit-files --state masked;;
            "se" ) systemctl list-unit-files --state=enabled;;
            "sd" ) systemctl list-unit-files --state=disabled;;
            "ss" ) systemctl list-unit-files --state=static;;
            "ue" ) systemctl --user list-unit-files --state=enabled;;
            "ud" ) systemctl --user list-unit-files --state=disabled;;
            "us" ) systemctl --user list-unit-files --state=static;;
            *) echo -e $hmsg012391299TMP ;;
        esac
    else
        echo -e $hmsg012391299TMP
    fi

    # Utilizei o unset para limpar a variável por que não há
    # necessidade de ela existir depois que sair da função.
    unset hmsg012391299TMP
}

# Lista usuários
usuarios(){
    hmsg012391299TMP="'$@' não é uma opção válida.\n\nAjuda: usuarios [OPÇÂO]\n r     : Mostra com o usuário root\n c     : Mostra usuários criados sem o serviços\n s	: Mostra usuários de serviços\n S	: Mostra usuários do samba\n\n Exemplo:\n\n usuarios r\n usuarios"

    if [ "$#" -eq 0 ]; then
        cut -d \: -f1 /etc/passwd
    elif [ "$#" -eq 1 ]; then
        case "$1" in
            "r") awk -F : '$3 < 1 || $3 >= 1000 { print $1}' /etc/passwd;;
            "c") awk -F : '$3 >= 1000 { print $1}' /etc/passwd;;
            "s") awk -F : '$3 > 0 && $3 < 1000 { print $1}' /etc/passwd;;
            "S") sudo pdbedit -L  | cut -d \: -f1;;
            * ) echo -e $hmsg012391299TMP;;
        esac
    else
        echo -e $hmsg012391299TMP
    fi

    unset hmsg012391299TMP
}

Espero que lhe ajude de alguma forma, até mais!

3 Curtidas

@Eduardo_MS
Valeu…

Ficou mais limpa…

    unset hmsg012391299TMP

A aplicação do unset no final é interessante
Esta função é bem antiga, como funcionava nunca pensei em modificá-la.

Se puder veja o script

Acho que ficou bom, mas pode melhorar
Usei também o if, mas no modo simples.

2 Curtidas

Uma outra opção em vez do unset: quando tenho funções com variáveis que posso descartar imediatamente, eu utilizo a sintaxe funcao() ( comando1; comando2; ) que é inclusive prevista na POSIX (suportada também por shells mais simples como dash, mksh, etc.). Ela roda o código da função num shell paralelo, sem mexer no que está rodando atualmente.

No tópico que eu fiz com o mesmo propósito, você vê que todas as minhas funções que mexem com variáveis são “insuladas” assim.

cppwr() ( # em vez de {
# ...
GOV=$(LC_ALL=C cpupower frequency-info -p | grep -o '"[a-z]\+"' | tr -d '"') # Essa variável está sendo definida num "shell paralelo", não vai afetar o shell principal
#...
) # em vez de }

Outra opção é usar local variavel no começo da função, para o shell entender que a variável é específica daquele bloco (alguns shells mais minimalistas não sabem mexer com isso, no entanto):

lsau() {
    local hmsg="\n '$@'" #...
    #...
}

ou

lsau() {
    local hmsg
    hmsg="Ajuda:"
    #...
}

Nem é necessário o monte de dígitos para não confundir acidentalmente com outra variável que o usuário/outra função talvez já esteja usando.

3 Curtidas

no KDE, que é a DE que eu uso, eu adiciono um atalho pra desligar e reiniciar o computador
CTRL + META + SHIFT + R pra reiniciar e CTRL + META + SHIFT + P pra desligar

a única alias que eu tenho no meu .bashrc é o update

alias update=‘yay -Syu --noconfirm’

isso é o que eu lembro :stuck_out_tongue:

Essa função é um wrapper pro apt, pkg2appimage e snap, funciona da seguinte forma, ao invés de usar um comando pra cada eu uso um comando só, ex:

app-install ubuntu-restricted-extras Leafpad photogimp

O script primeiro verifica se é possível fazer um AppImage, se sim, ele gera, se não verifica se é um snap, por fim se não for possível gerar um AppImage através do pkg2appimage, nem for um snap, ele tenta instalar usando o APT


function app-install() {
  local pasta_trabalho=$(mktemp -d)
  local debs=()
  cd ${pasta_trabalho}

  mkdir -p ${HOME}/.local/bin
  mkdir -p out

  for arg in ${@}; do
    wget -q --method=HEAD "https://raw.githubusercontent.com/AppImage/pkg2appimage/master/recipes/${arg}.yml" && {
      echo "${arg} vai ser um AppImage"
      pkg2appimage "${arg}"
    } || {
      wget -q --method=HEAD "https://snapcraft.io/${arg}" && {
        echo "${arg} vai ser um Snap"
        sudo snap install "${arg}"
      } || {
        echo "${arg} vai ser instalado usando o APT"
        debs+=(${arg})
      }
    }
  done

  [ ! "${#debs[@]}" = "0" ] && {
    sudo apt install ${debs[@]} --no-install-recommends
  }

  mv ./out/* $HOME/.local/bin

  cd ~
  rm -rf ${pasta_trabalho}
}

Ressuscitando esse tópico com alguns scripts que eu fiz (em spoilers porque são longos):

YouTube DL + Corte com base na descrição do vídeo
#! /bin/bash -ex

# Usei bash -ex no #!, melhor criar a pasta pra não ter erro
mkdir -p ~/.cache/youtube-multi-dl

# Conservar o cache se o download tiver sido pulado.
if [[ ! " $* " =~  " --skip-download " ]]; then rm -rf ~/.cache/youtube-multi-dl; fi

# Cria de novo pra garantir.
mkdir -p ~/.cache/youtube-multi-dl

# Baixar o vídeo e todas informações aí e Enviar o vídeo como link simbólico
# para a pasta de cache criada lá em cima.
# Foi a melhor maneira que eu achei para garantir que a extensão ia ser
# detectada corretamente na hora de cortar o vídeo.
youtube-dl "$@" --write-info-json --exec 'ln -s "$PWD"/{} ~/.cache/youtube-multi-dl'

# Função para cortar o vídeo
_cut() {
        # Checar se o arquivo existe para não esbarrar no -ex.
        if [ ! -f "$4" ]; then
                ffmpeg -nostdin \
                -loglevel 8 \
                -i "$1" \
                -c copy \
                -ss `[ -n "$2" ] && echo "$2" || echo 0` \
                `[ -n "$3" ] && echo -to "$3"` \
                -- "$4"
        else
                echo "$4" já existe.
        fi
}

# Se não tiver nada no cache, só pula o for.
shopt -s nullglob
for OUTFILE in ~/.cache/youtube-multi-dl/*; do
        # Pegar o caminho ao qual o link simbólico faz referência.
        FILENAME=$(realpath "$OUTFILE")

        # Pegar o Json com informações (inclusive os cortes).
        INFOFILE=${FILENAME%.*}.info.json

        # Pegar a extensão do arquivo.
        EXT=${FILENAME##*.}

        i=0
        # Loopar nos cortes até não ter mais capítulos para cortar.
        while [ ! "`jq ".chapters[${i}]" "$INFOFILE"`" = null ]; do
                readarray -t INFO < <(jq -r ".chapters[${i}].title,.chapters[${i}].start_time,.chapters[${i}].end_time" -- "$INFOFILE")
                _cut "$FILENAME" "${INFO[1]}" "${INFO[2]}" "${INFO[0]}"."$EXT"
                i=$((i+1))
        done

        # Se tiver um comentário com as timestamps, cola na pasta de saída como
        # um arquivo de texto chamado CUTS sem extensão. O script se vira para
        # cortar o arquivo.
        if [ -f CUTS ]; then
                TIME_PAT='[0-9]+(:[0-5]?[0-9]){1,2}' # HH:MM:SS em regex

                sA= #começo de um corte.
                sB= # final de um corte.
                sOLDOUT= #Nome do título anterior. Caso haja apenas uma timestamp por
                # lina.

                # Essas três variáveis vão fazer sentido no ELSE.
                while read -r LINE; do
                        # Tirar tudo quanto é timestamp, depois espaço e pontuação no come-
                        # ço para achar o título do corte.
                        read -r TITLE < <(sed -r "s/.*(${TIME_PAT})//g" <<<$LINE | sed -r 's/^([[:punct:]]|[[:space:]])+//g')
                        # Achar as timestamps pelo Regex.
                        readarray -t TIMES < <(grep -Eo "$TIME_PAT" <<<$LINE)

                        if [ -n "${TIMES[0]}" ] && [ -n "${TIMES[1]}" ]; then
                                # Achou duas timestamps (começo e fim, nessa ordem)
                                _cut "$FILENAME" "${TIMES[0]}" "${TIMES[1]}" "$TITLE"."$EXT"

                                # Para caso ele fique alternado entre começo e fim e só começo
                                # de timestamp
                                sA=${TIMES[1]}
                                sOLDOUT="`uuidgen`"."$EXT"

                        elif [ -z "${TIMES[0]}" ] && [ -z "${TIMES[1]}" ]; then
                                # Zero timestamps nessa linha. Só pula.
                                continue
                        else
                                # Só uma timestamp por linha. Significa que entre as time-
                                # stamps há um corte.

                                # Timestamp atual - final de um corte.
                                sB=$TIMES

                                if [ -z "$sA" ]; then 
                                        : # Opa. A gente nem tinha começado a cortar.
                                else
                                        # Corte que foi anunciado linha passada.
                                        _cut "$FILENAME" "$sA" "$sB" "$sOLDOUT"
                                fi

                                # O final de um, o começo de outro.
                                sA=$sB

                                # Pegar o título do corte que começa agora.
                                sOLDOUT="$TITLE"."$EXT"
                        fi

                done < CUTS

                if [ -n "$sOLDOUT" ]; then # Caso haja um corte sobrando...
                        # Corta a partir do último começo de corte registrado.
                        _cut "$FILENAME" "$sA" "" "$sOLDOUT"
                fi
        fi

done

Requer youtube-dl e jq.
Fiz o possível para o --help do Youtube-DL se aplicar a ele.

Remover anotações de PDF
#! /bin/sh -ex
# https://gist.github.com/stefanschmidt/5248592

test -f "$1"

OUT=$2
if [ -z "$OUT" ]; then
        OUT=$(basename "$1")
        while [ -f "$OUT" ]; do
                OUT="${OUT%.pdf}".un.pdf
        done
fi

pdftk "$1" output - uncompress | LANG=C LC_CTYPE=C sed -n '/^\/Annots/!p' | pdftk - output "$OUT" compress

Requer pdftk.
Uso: pdfunnanotate coisa.pdf saida.pdf

Compressor de imagens do PDF
#!/bin/bash -e
# http://www.alfredklomp.com/programming/shrinkpdf

cleanup() {
        if [ -d "$WORKDIR" ]; then
                rm -r "$WORKDIR"
        fi
}

DPI=$3
[ -z "$DPI" ] && DPI=72

OUT=$2
[ -z "$OUT" ] && OUT=-

GS_OPTS="
        -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite
        -dAutoRotatePages=/None
        -dColorImageDownsampleType=/Bicubic
        -dColorImageResolution=$DPI
        -dGrayImageDownsampleType=/Bicubic
        -dGrayImageResolution=$DPI
        -dMonoImageDownsampleType=/Subsample
        -dMonoImageResolution=$DPI
"

WORKDIR="$(dirname "$1")"/.tmp"$(tr -d '[[:space:]]' <<<$1)"
mkdir -p "$WORKDIR"

trap INT TERM EXIT cleanup

gs -o "$WORKDIR"/bg.pdf $GS_OPTS -dFILTERTEXT -dPDFSETTINGS=/screen "$1" &
gs -o "$WORKDIR"/input.pdf $GS_OPTS -dFILTERIMAGE -dFILTERVECTOR "$1"

wait # wait for all jobs to finish...

pdftk "$WORKDIR"/input.pdf multibackground "$WORKDIR"/bg.pdf output "$OUT"

Requer ghostscript e pdftk.
Uso pdfcompress entrada.pdf saida.pdf RESOLUÇÃO
Resolução é em pontos por polegada (padrão: 72).

Conversor de imagens e documentos
#! /bin/sh

if test -z "$1"; then
        echo 'Comece com um nome de arquivo ou extensão'
        exit 1
fi

# $1 é um arquivo, pdf logo
if test -f "$1"; then
        OUTF=pdf
fi

for arg; do

        if test -z "$arg"; then
                echo 'Argumento vazio!'
                exit 1
        fi

        if ! test -f "$arg"; then
                # Não é um arquivo, é uma extensão de arquivo
                OUTF=$1
                continue
        fi

        MIME=`file --brief --mime-type "$arg"`
        M=`echo $MIME | cut -d/ -f1`

        CONVCMD=
        if [ "$M" = image -o "$M" = video -o "$MIME" = application/pdf ]; then
                CONVCMD='mogrify -format'
        elif [ "$M" = application -o "$M" = text ]; then
                CONVCMD='libreoffice --headless --convert-to'
        else
                echo 'O arquivo' "$arg" 'parece não ser suportado.'
                exit 1
        fi

        ($CONVCMD $OUTF "$arg" && echo Arquivo "$arg" convertido para "${arg%.*}.${OUTF}". || echo Conversão de "$arg" falhou.) &
done
wait

Requer o LibreOffice e o ImageMagick.
Uso: conv FORMATO1 ARQUIVO(S) FORMATO2 ARQUIVO(S)

Agora que estou vendo o quanto eu usei arquivos PDF em 2020.

2 Curtidas

Vi esse script num vídeo do YouTube (já dizendo que não é bem ideia minha), mas ele é muito bom e gostaria de compartilhar aqui. É um seletor de emoji simples, baseado no rofi/dmenu (programas leves que iniciam rápido, diferente de um certo programa cof cof seletor de emoji do KDE cof cof)

Requisitos são rofi (ou dmenu) e xclip, e um arquivo com uma lista de emojis (um por linha).

Gerando a tal lista de emoji

A maneira mais direta de fazer um arquivo com todos os emojis do mundo, um por linha, é ir direto na fonte, o Unicode Consortion:

# Pegar a lista oficial de emojis
wget -q 'https://unicode.org/Public/emoji/13.1/emoji-test.txt' -O - |
# Pegar apenas emojis completos
grep '; fully-qualified' |
# Filtrar informações irrelevantes (código, versão que apareceu, etc.) - deixar só nome e emoji em si
cut -d'#' -f2 | cut -d' ' -f2,4- \
> ~/.config/emoji.list # Soltar a saída para um arquivo, com a lista de emojis.
Conteúdo do arquivo de script em si - versão rofi
#! /bin/sh
# Variável com o emoji.
EMOJI=$(
        # Ler o arquivo ~/.config/emoji.list e pedir para o usuário escolher um.
        <~/.config/emoji.list rofi -dmenu -i -sync -p 'Emoji' |
        cut -d' ' -f1 # Cortar a descrição.
)
# Emoji selecionado, não vazio:
if [ -n "$EMOJI" ]; then
        # Passar para área de transferência
        echo "$EMOJI" | xclip
        # Notificar
        notify-send "$EMOJI foi copiado para área de transferência." -a 'Seletor de emoji'
fi
Conteúdo do arquivo de script em si - versão dmenu
#! /bin/sh
# Variável com o emoji.
EMOJI=$(
        # Ler o arquivo ~/.config/emoji.list e pedir para o usuário escolher um.
        <~/.config/emoji.list dmenu -i -l 20 |
        cut -d' ' -f1 # Cortar a descrição.
)
# Emoji selecionado, não vazio:
if [ -n "$EMOJI" ]; then
        # Passar para área de transferência
        echo "$EMOJI" | xclip
        # Notificar
        notify-send "$EMOJI foi copiado para área de transferência." -a 'Seletor de emoji'
fi
1 Curtida