วิธีนี้เป็นแบบพกพาไปยังระบบ Unix ใด ๆ แต่ขึ้นอยู่กับการทำงานของ GNU ทุบตี cd -P
ที่จะทำให้มันไม่น่าเกลียด
วางสิ่งนี้ (หรือรุ่นอื่นด้านล่างซึ่งเก็บรักษาไดเรกทอรีตรรกะ) ไว้ในของคุณ ~/.bashrc
(หรือ .zshrc
หรืออะไรก็ตาม) ดังนั้นมันจะทำงานสำหรับเชลล์แบบโต้ตอบทุกอัน (ภายในและภายนอกหน้าจอ):
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
ดังนั้นคุณสามารถเปิดหน้าต่างหน้าจอใหม่และ cds 5
จะนำคุณไปยัง cwd ของเชลล์ในหน้าต่าง 5
สิ่งนี้สามารถใช้งานได้กับเปลือกหอยที่เริ่มด้านนอกของหน้าจอและแม้กระทั่งก่อนที่เซสชันหน้าจอของคุณจะมีอยู่ (เนื่องจากในกรณีดังกล่าวการขยายแบบกลมเกิดขึ้นเมื่อรันไทม์ของ cds
มากกว่าตอนที่มันถูกกำหนดเช่นเดียวกับการแฮ็กตัวแปรอาเรย์ที่ฉันใส่ความเห็นเพราะมันแย่กว่าในทุก ๆ ด้าน)
ค่าใช้จ่ายทั้งหมด:
- ในทุกการเริ่มต้นเชลล์แบบโต้ตอบ:
- 8 บรรทัดที่ไม่ใช่ความคิดเห็นของรหัสในการแยกวิเคราะห์
- ln -sTf ไปยังไดเร็กทอรีบน tmpfs
- โอเวอร์เฮดหน่วยความจำอย่างต่อเนื่องหลังจากเชลล์เริ่มทำงาน:
- 1 shell var และ 1 small function
- การจัดเก็บ:
- ไดเรกทอรีหนึ่ง symlink ต่อหน้าต่างหน้าจอ (ไม่ถูกลบหลังจากปิดหน้าต่าง)
- ต่อคำสั่ง:
ไม่มี cd -P
, \w
ในของคุณ $PS1
จะขยายเป็น /proc/3069/cwd
ไม่ใช่เส้นทางที่เป็นที่ยอมรับ (ตามด้วย symlink) ที่คุณได้รับ -P
.
เวอร์ชันที่ใช้ PROMPT_COMMAND สามารถแก้ไขได้ cds()
เพื่อ cd เพื่อนำคุณไปยังไดเรกทอรีโลจิคัล (เก็บ CWD เป็นข้อความในไฟล์แทนที่จะเป็น symlink pwd > "$CDS_DIR/$WINDOW"
เป็นเพียง shell builtin ดังนั้นค่าใช้จ่ายน้อยกว่า fork / execing ไบนารี นอกจากนี้ยังบันทึกปัญหาในการหลีกเลี่ยง GNU ที่หายไป readlink
บนบางระบบที่ไม่ใช่ Linux) สิ่งนี้จะมีประโยชน์หากคุณมักจะทำงานใน symlink ไปยังไดเรกทอรีที่ pwd -P
(และ /bin/pwd
) ไม่เหมือนกับ pwd
.
คุณสามารถแทนที่ cd
, pushd
และ popd
builtins พร้อมฟังก์ชั่นที่อัปเดต symlink แทนที่จะทำทุกคำสั่ง ด้วยการตั้งค่านั้นการใช้สิ่งโต้ตอบเช่น (cd foo; command there)
จะหลอกการตั้งค่าของคุณเพราะ cd
ที่ทำงานใน subshell จะอัพเดท symlink แต่ไม่มีการแก้ไข pwd ของกระบวนการเชลล์หลัก
ตกลงนี่เป็น "รุ่นอื่น" ที่เกี่ยว cd
, pushd
และ popd
และจะนำคุณไปยังไดเรกทอรีโลจิคัลเดียวกับเชลล์ในหน้าต่างหน้าจอใด ๆ :
# 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
ค่าใช้จ่าย: open(2)
และ write(2)
เป็น tmpfs สำหรับทุกคน cd
, pushd
และ popd
คุณพิมพ์หรือวางมิฉะนั้นจะเหมือนกัน ยังคงไม่เจ็บในระบบใด ๆ ที่ทรงพลังพอที่จะรัน bash
และ screen
ในที่แรก. :)
ให้เครดิตกับ https://superuser.com/a/54161/20798 สำหรับแนวคิดของ hooking cd ฉันชอบที่ดีกว่ามาก PROMPT_COMMAND
. พบว่าในขณะที่มองเพื่อดูว่ามีคนอื่นคิดค้นนี้และไม่ว่าฉันควรโพสต์ที่นี่หรือบน https://unix.stackexchange.com/ .
ฉันใช้ bash-isms (เช่น [[ ]]
) เพราะฉันคิดว่า zsh ก็สนับสนุนพวกเขาด้วยและหวังว่าจะไม่มีใครใช้ POSIX sh เป็นเชลล์เชิงโต้ตอบของพวกเขา