Este método é portátil para qualquer sistema Unix, mas depende da funcionalidade do cd -P
do GNU bash para torná-lo não feio.
Coloque isto (ou a outra versão abaixo, que preserva diretórios lógicos) no seu ~/.bashrc
(ou .zshrc
ou qualquer outro), então ele é executado para cada shell interativo (dentro e fora da tela):
CDS_PREFIX="/var/run/screen/S-$USER" # screen uses this already
#CDS_PREFIX="/dev/shm/screen-$USER" # if /var/run isn't on tmpfs
# $STY = a string unique to the screen session
if [[ $STY ]]; then
CDS_DIR="$CDS_PREFIX/dirs.$STY"
unset CDS_PREFIX
[[ -d $CDS_DIR ]] || mkdir -m 700 -p "$CDS_DIR"
# old cmd-every-prompt design: avoids breakage if you run interactive bash from bash, then exit
# Also, use this on systems without a /proc/<pid>/cwd
#PROMPT_COMMAND='[[ $WINDOW ]] && ln -sf "$PWD" "$CDS_DIR/$WINDOW"'
ln -sTf "/proc/$$/cwd" "$CDS_DIR/$WINDOW" # -T saves a stat call
cds() { cd -P "$CDS_DIR/$@"; }
else
# CDS_DIR=( "$CDS_PREFIX"/dirs.* ) # cds will use the first array element
cds() { cd -P "$CDS_PREFIX/"dirs.*/"$@"; } # even support shells started before screen. cd with multiple args takes the first one without complaint.
fi
Assim, você pode abrir uma nova janela de tela e cds 5
levará você ao cwd do shell na janela 5.
Isso funciona mesmo para shells iniciados FORA da tela, e mesmo antes da sessão de tela existir. (já que, nesse caso, a expansão glob ocorre no tempo de execução de cds
, em vez de quando foi definida como com o hack de array-variable que comentei, já que é pior em todos os aspectos.)
Sobrecarga total:
- em todas as inicializações do shell interativo:
-
- 8 linhas de código sem comentário para analisar.
-
- uma estatística
-
- a ln -sTf para um diretório no tmpfs
Sobrecarga de memória contínua após o início do shell:
-
- 1 shell var e 1 pequena função
-
- sem ambiente vars
- armazenamento:
-
- um diretório de um link simbólico por janela de tela (não é removido depois que o windows fecha)
- por comando:
-
- nenhum
Sem cd -P
, o \w
no seu $PS1
expandiria para /proc/3069/cwd
, em vez do caminho canônico (links simbólicos seguidos) obtido com -P
.
A versão que usa PROMPT_COMMAND pode modificar cds()
para cd para levá-lo ao diretório lógico. (Armazene o CWD como texto em um arquivo, em vez de um link simbólico. pwd > "$CDS_DIR/$WINDOW"
é apenas um shell embutido, portanto menos sobrecarga do que fork / execução de um binário. Também economiza o trabalho de contornar o GNU readlink
ausente em alguns Sistemas Linux.) Isso seria útil se você trabalha frequentemente em links simbólicos para diretórios, onde pwd -P
(e /bin/pwd
) não é o mesmo que pwd
.
Você pode substituir as funções cd
, pushd
e popd
por funções que atualizam o symlink, em vez de fazer isso em todos os prompts. Com essa configuração, o uso interativo de coisas como (cd foo; command there)
enganará sua configuração, porque o cd
que é executado no subshell atualizará o symlink, mas sem modificar o pwd do processo principal do shell.
Ok, aqui está a "outra versão", que conecta cd
, pushd
e popd
e levará você ao mesmo diretório lógico que seu shell em qualquer janela de tela:
# Use this version on systems without '/proc/<pid>/cwd', or for logical directories (non-dereferencing of symlinks).
CDS_PREFIX="/var/run/screen/S-$USER"
#CDS_PREFIX="/dev/shm/screen-$USER"
if [[ $STY ]]; then
CDS_DIR="$CDS_PREFIX/dirs.$STY"
unset CDS_PREFIX
[[ -d $CDS_DIR ]] || mkdir -m 700 -p "$CDS_DIR"
function cd () { command cd "$@"; pwd > "$CDS_DIR/$WINDOW"; }
function pushd () { command pushd "$@"; pwd > "$CDS_DIR/$WINDOW"; }
function popd () { command popd "$@"; pwd > "$CDS_DIR/$WINDOW"; }
#PROMPT_COMMAND='[[ $WINDOW ]] && pwd > "$CDS_DIR/$WINDOW"'
if [[ -e "$CDS_DIR/$WINDOW" && ! -f "$CDS_DIR/$WINDOW" ]]; then
rm -f "$CDS_DIR/$WINDOW" # could exist if switching from symlink-to-dir style
fi
cd .
# cds() { local d="$(<"$CDS_DIR/$1")"; shift; cd "$d" "$@"; }
cds() { cd "$(<"$CDS_DIR/$1")"; }
else
# CDS_DIR=( "$CDS_PREFIX"/dirs.* ) # cds will use the first array element
cds() { cd "$(<"$CDS_PREFIX/"dirs.*/"$1")"; } # even support shells started before screen.
fi
Sobrecarga: um open(2)
e write(2)
para tmpfs para cada cd
, pushd
e popd
que você digitar ou colar. Caso contrário, o mesmo. Ainda não vai doer, em qualquer sistema poderoso o suficiente para executar bash
e screen
em primeiro lugar. :)
Acredite no link para ter a ideia de criar um CD. Eu gosto muito melhor do que PROMPT_COMMAND
. Descobri que, enquanto procurava para ver se alguém havia inventado isso, e se eu deveria postar aqui ou no link .
Eu usei alguns bash-isms (como [[ ]]
) porque acho que o zsh também os suporta, e esperamos que ninguém esteja usando o POSIX sh como seu shell interativo.