可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In a bash script, I want to get the cursor column in a variable. It looks like using the ANSI escape code {ESC}[6n
is the only way to get it, for example the following way:
# 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
Unfortunately, this prints characters to the standard output and I want to do it silently. Besides, this is not very portable...
Is there a pure-bash way to achieve this ?
回答1:
You have to resort to dirty tricks:
#!/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))
回答2:
I know it may be solved by know, but you could just tell read to work silently with "-s" :
echo -en "\E[6n" read -sdR CURPOS CURPOS=${CURPOS#*[}
And then CURPOS is equal to something like "21;3".
回答3:
In the interests of portability I've had a go at making a vanilla POSIX-compatible version that will run in shells like dash:
#!/bin/sh exec < /dev/tty oldstty=$(stty -g) stty raw -echo min 0 tput u7 > /dev/tty sleep 1 IFS=';' read -r row col stty $oldstty row=$(expr $(expr substr $row 3 99) - 1) # Strip leading escape off col=$(expr ${col%R} - 1) # Strip trailing 'R' off echo $col,$row
...but I can't seem to find a viable alternative for bash's 'read -d'. Without the sleep, the script misses the return output entirely...
回答4:
The tput commands are what you need to use. simple, fast, no output to the screen.
#!/bin/bash col=`tput col`; line=`tput line`;