উল্লম্ব কার্সার অবস্থান পান


10

এটি বেশ অদ্ভুত শোনায়, তবে আমি জানি যে এইভাবে বাশের মধ্যে উল্লম্ব কার্সার অবস্থানটি কীভাবে সেট করা যায়:

echo -e "\e[12H"

এটি কার্সারটিকে 12 তম লাইনে স্থানান্তরিত করে (1 দিয়ে শুরু করে)।

সুতরাং আমি কীভাবে লিনাক্স ব্যাশ ব্যবহার করে কার্সার অবস্থান (লাইন নম্বর) পেতে পারি? এটি সহায়ক হবে যদি আমি এই মানটি কেবল একটি ভেরিয়েবলের মধ্যে সঞ্চয় করতে পারি তাই আমি এটি দিয়ে গণনা করতে পারি।

সম্পাদনা করুন:

এই ত্রুটিটি আমি পেয়েছি:

$ sh rowcol.sh
-en
    read: 9: Illegal option -d
                              test.sh: 12: Bad substitution

আরও দেখুন একটি উদাহরণ স্ক্রিপ্ট (সরলতম না, কারণ এক যে অতিরিক্ত সীমাবদ্ধতা ছিল)।
গিলস 'অশুভ হওয়া বন্ধ করুন'

উত্তর:


5

আমি এসও সম্পর্কিত একই নিবন্ধ থেকে কয়েকটি উদাহরণ ব্যবহার করতে সক্ষম হয়েছি: শিরোনাম: বাশায় কার্সার অবস্থানটি কীভাবে পাবেন? । আমি এগুলি এখানে পোস্ট করছি কেবল তারা দেখায় যে তারা কাজ করে এবং সমাধানের বিষয়বস্তু আসলে ইউ ও এল-তেও থাকে।

বাশ সমাধান

একটি স্ক্রিপ্ট ভিতরে থেকে

#!/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))

echo "(row,col): $row,$col"

দ্রষ্টব্য: আমি আউটপুটটি সামান্য পরিবর্তন করেছি!

উদাহরণ

$ ./rowcol.bash 
(row,col): 43,0
$ clear
$ ./rowcol.bash 
(row,col): 1,0

ইন্টারেক্টিভ শেল

এই কমান্ড চেইন কার্সারের সারি এবং কলাম অবস্থানগুলি পাওয়ার জন্য কাজ করেছে:

$ echo -en "\E[6n";read -sdR CURPOS; CURPOS=${CURPOS#*[};echo "${CURPOS}"

উদাহরণ

$ echo -en "\E[6n";read -sdR CURPOS; CURPOS=${CURPOS#*[};echo "${CURPOS}"
13;1
$ clear
$ echo -en "\E[6n";read -sdR CURPOS; CURPOS=${CURPOS#*[};echo "${CURPOS}"
2;1

দ্রষ্টব্য: এই পদ্ধতিটি কোনও ধরণের স্ক্রিপ্ট থেকে ব্যবহারযোগ্য বলে মনে হচ্ছে না। একটি ইন্টারেক্টিভ টার্মিনালের সাধারণ কমান্ডগুলিও আমার পক্ষে কার্যকর হয়নি। উদাহরণ স্বরূপ:

$ pos=$(echo -en "\E[6n";read -sdR CURPOS; CURPOS=${CURPOS#*[};echo "${CURPOS}")

কেবল অনির্দিষ্টকাল ধরেই ঝুলছে।

ড্যাশ / শ সমাধান

একটি স্ক্রিপ্ট ভিতরে থেকে

এই সমাধানটি উবুন্টু / ডেবিয়ান সিস্টেমগুলির জন্য যা স্টক আসে dash, যা পসিক্স অনুগত। এই কারণে, readকমান্ডটি -dঅন্যান্য পার্থক্যের মধ্যে স্যুইচটিকে সমর্থন করে না ।

এটির কাছাকাছি sleep 1আসার জন্য এই সমাধানটি রয়েছে যা -dস্যুইচের জায়গায় একটি ব্যবহার করে । এটি আদর্শ নয় তবে কমপক্ষে একটি কার্যক্ষম সমাধান সরবরাহ করে।

#!/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 "(row,col): $col,$row"

উদাহরণ

$ ./rowcol.sh 
(row,col): 0,24
$ clear
$ ./rowcol.sh 
(row,col): 0,1

ইন্টারেক্টিভ শেল

আমি একটি কার্যক্ষম সমাধান খুঁজে পাইনি যা কেবলমাত্র shএকটি ইন্টারেক্টিভ শেলের জন্য কাজ করেছিল ।


এটি কেবল বাশ দিয়ে কাজ করবে বলে মনে হচ্ছে। এবং sh সঙ্গে নয়। আমি ব্যক্তিগতভাবে শ। সুতরাং আমি কীভাবে এই ব্যবহার করতে পারি?
ব্রেনস্টোন

1
@ ব্রেনস্টোন - আমাকে গবেষণা করতে দিন এবং আমি কোনও উপায় খুঁজে পাচ্ছি না তা দেখতে দিন।
slm

sh rowcol.sh। আপনি প্রথম লাইনে ( #!/bin/bashবা #!/bin/sh) কী রেখেছেন বা ফাইলটির কী শেষ আছে তা বিবেচ্য নয়!
ব্রেনস্টোন

@ ব্রেনস্টোন - তবে আমি মনে করি shএটি কেবল একটি সামঞ্জস্যতা মোড bash। আমি যখন এটি করি ( sh rowcol.bash) এটি কাজ করে, তখন কি এটি আপনার পক্ষে কার্যকর হয় না?
slm

1
@ ব্রেনস্টোন - আপনি একটি উপাধি তৈরি করতে পারেন alias sh=bash,?
slm

17

-pপরিবর্তে বিকল্পটি ব্যবহার করে echoআমি কোনও স্ক্রিপ্টে ঝুলন্ত সমস্যার সমাধান পেয়েছি। দিয়ে পরীক্ষিত GNU bash, version 3.00.16(1)-release (x86_64-redhat-linux-gnu)

IFS=';' read -sdR -p $'\E[6n' ROW COL;echo "${ROW#*[}"

ইন্টারেক্টিভ বা স্ক্রিপ্টে কাজ করে:

#!/usr/bin/env bash
function pos
{
    local CURPOS
    read -sdR -p $'\E[6n' CURPOS
    CURPOS=${CURPOS#*[} # Strip decoration characters <ESC>[
    echo "${CURPOS}"    # Return position in "row;col" format
}
function row
{
    local COL
    local ROW
    IFS=';' read -sdR -p $'\E[6n' ROW COL
    echo "${ROW#*[}"
}
function col
{
    local COL
    local ROW
    IFS=';' read -sdR -p $'\E[6n' ROW COL
    echo "${COL}"
}
tput sc         # Save cursor position
tput cup 5 10   # Move to row 6 col 11
POS1=$(pos)     # Get the cursor position
ROW1=$(row)
COL1=$(col)
tput cup 25 15  # Move to row 25 col 15
POS2=$(pos)     # Get the cursor position
ROW2=$(row)
COL2=$(col)
tput rc # Restore cursor position
echo $BASH_VERSION
echo $POS1 $ROW1 $COL1
echo $POS2 $ROW2 $COL2

আউটপুট:

$। / Cursor.sh
3.00.16 (1) -release
6; 11 6 11
26; 16 26 16

এটি খুব ভাল কাজ করে। তবে দুঃখের বিষয়, এটি ব্যাকগ্রাউন্ড প্রক্রিয়াগুলিতে কাজ করে না এবং স্ক্রিন স্ক্রোল হিসাবে, সংরক্ষিত কলামের নীচে লাইনটি পরিবর্তিত হয়।
লিওনডেপিয়ন

4

আপনি মাধ্যমে কার্সার অবস্থানে পেতে পারেন ANSI CSI DSR(ডিভাইস স্থিতি প্রতিবেদন): \e[6n। নোট করুন এটি ANSI CSR CUPআপনার প্রশ্নের ক্ষেত্রে উল্লিখিত (কার্সার অবস্থান) এর অনুরূপ বিন্যাসে এটি প্রদান করে, তবে এটি ফর্মটি অনুসরণ করে \e[n;mR(যেখানে এনটি সারি এবং এম কলামটি রয়েছে)।

উইকিপিডিয়ায় এএনএসআই পলায়নের কোডগুলির আরও বিশদ ।

ভেরিয়েবলের মান ধরে রাখার জন্য, স্ট্যাক ওভারফ্লোতে এটির উত্তর দেওয়া হয়েছিল

পূর্ববর্তী উত্তর / মন্তব্যে উল্লিখিত (এবং উইকিপিডিয়া নিবন্ধে বিস্তারিত), এই কোডগুলি সর্বদা পোর্টেবল হয় না (টার্মিনাল থেকে টার্মিনাল এবং ওএস থেকে ওএস) port আমি এখনও মনে করি এটি আরও ভালভাবে টার্মক্যাপ / অভিশাপগুলির সাথে পরিচালিত হয়েছে;)


এবং আমি কীভাবে এটি একটি ভেরিয়েবলের মধ্যে সঞ্চয় করতে পারি?
ব্রেইনস্টোন

আমি এটি কাজ পেতে পারি না। আমি সর্বদা সমস্যা হয় echo -e, echo -enএবং read ...। কোডটি ফাইলটিতে উপস্থিত থাকলেই এটি ঘটে! আমি সত্যিই এই বুঝতে পারি না!
ব্রেইনস্টোন

দেখে মনে হচ্ছে কিছুটা সেটিং ভেঙেছি। echo -eআগে কাজ করেছেন কিন্তু এখন তা হয় না! কী কারণে এটি হতে পারে এবং আমি কীভাবে এটি পুনরুদ্ধার করব?
ব্রেইনস্টোন

2

পসিক্স shসিনট্যাক্স সহ:

if [ -t 0 ] && [ -t 1 ]; then
  old_settings=$(stty -g) || exit
  stty -icanon -echo min 0 time 3 || exit
  printf '\033[6n'
  pos=$(dd count=1 2> /dev/null)
  pos=${pos%R*}
  pos=${pos##*\[}
  x=${pos##*;} y=${pos%%;*}
  stty "$old_settings"
fi
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.