在bash脚本中,我想在变量中获取游标列.看起来使用ANSI转义码{ESC}[6n是获取它的唯一方法,例如以下方式:
# Query the cursor position
echo -en '\033[6n'
# Read it to a variable
read -d R CURCOL
# Extract the column from the variable
CURCOL="${CURCOL##*;}"
# We have the column in the variable
echo $CURCOL
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会将字符打印到标准输出,我想静静地进行.此外,这不是很便携......
是否有一种纯粹的bash方式来实现这一目标?
Pau*_*ce. 34
你必须采取肮脏的技巧:
#!/bin/bash
# based on a script from http://invisible-island.net/xterm/xterm.faq.html
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
# on my system, the following line can be replaced by the line below it
echo -en "\033[6n" > /dev/tty
# tput u7 > /dev/tty # when TERM=xterm (and relatives)
IFS=';' read -r -d R -a pos
stty $oldstty
# change from one-based to zero based so they work with: tput cup $row $col
row=$((${pos[0]:2} - 1)) # strip off the esc-[
col=$((${pos[1]} - 1))
Run Code Online (Sandbox Code Playgroud)
小智 9
我知道它可以通过知道来解决,但你可以告诉read用"-s"静默工作:
echo -en "\E[6n"
read -sdR CURPOS
CURPOS=${CURPOS#*[}
Run Code Online (Sandbox Code Playgroud)
然后CURPOS等于"21; 3"之类的东西.
小智 5
如果其他人正在寻找这个,我在这里遇到了另一个解决方案:https : //github.com/dylanaraps/pure-bash-bible#get-the-current-cursor-position
下面是一个带有注释的稍微修改的版本。
#!/usr/bin/env bash
#
# curpos -- demonstrate a method for fetching the cursor position in bash
# modified version of https://github.com/dylanaraps/pure-bash-bible#get-the-current-cursor-position
#
#========================================================================================
#-
#- THE METHOD
#-
#- IFS='[;' read -p $'\e[6n' -d R -a pos -rs || echo "failed with error: $? ; ${pos[*]}"
#-
#- THE BREAKDOWN
#-
#- $'\e[6n' # escape code, {ESC}[6n;
#-
#- This is the escape code that queries the cursor postion. see XTerm Control Sequences (1)
#-
#- same as:
#- $ echo -en '\033[6n'
#- $ 6;1R # '^[[6;1R' with nonprintable characters
#-
#- read -p $'\e[6n' # read [-p prompt]
#-
#- Passes the escape code via the prompt flag on the read command.
#-
#- IFS='[;' # characters used as word delimiter by read
#-
#- '^[[6;1R' is split into array ( '^[' '6' '1' )
#- Note: the first element is a nonprintable character
#-
#- -d R # [-d delim]
#-
#- Tell read to stop at the R character instead of the default newline.
#- See also help read.
#-
#- -a pos # [-a array]
#-
#- Store the results in an array named pos.
#- Alternately you can specify variable names with positions: <NONPRINTALBE> <ROW> <COL> <NONPRINTALBE>
#- Or leave it blank to have all results stored in the string REPLY
#-
#- -rs # raw, silent
#-
#- -r raw input, disable backslash escape
#- -s silent mode
#-
#- || echo "failed with error: $? ; ${pos[*]}"
#-
#- error handling
#-
#- ---
#- (1) XTerm Control Sequences
#- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Functions-using-CSI-_-ordered-by-the-final-character_s_
#========================================================================================
#-
#- CAVEATS
#-
#- - if this is run inside of a loop also using read, it may cause trouble.
#- to avoid this, use read -u 9 in your while loop. See safe-find.sh (*)
#-
#-
#- ---
#- (2) safe-find.sh by l0b0
#- https://github.com/l0b0/tilde/blob/master/examples/safe-find.sh
#=========================================================================================
#================================================================
# fetch_cursor_position: returns the users cursor position
# at the time the function was called
# output "<row>:<col>"
#================================================================
fetch_cursor_position() {
local pos
IFS='[;' read -p $'\e[6n' -d R -a pos -rs || echo "failed with error: $? ; ${pos[*]}"
echo "${pos[1]}:${pos[2]}"
}
#----------------------------------------------------------------------
# print ten lines of random widths then fetch the cursor position
#----------------------------------------------------------------------
#
MAX=$(( $(tput cols) - 15 ))
for i in {1..10}; do
cols=$(( $RANDOM % $MAX ))
printf "%${cols}s" | tr " " "="
echo " $(fetch_cursor_position)"
done
Run Code Online (Sandbox Code Playgroud)
您可以通过以下方式获取 bash 中的光标位置:
xdotool getmouselocation
$ x:542 y:321 screen:0 window:12345678
Run Code Online (Sandbox Code Playgroud)
您还可以通过以下方式在终端上轻松测试它:
实时变体 1:
watch -ptn 0 "xdotool getmouselocation"
Run Code Online (Sandbox Code Playgroud)
实时变体 2:
while true; do xdotool getmouselocation; sleep 0.2; clear; done
Run Code Online (Sandbox Code Playgroud)