如何在 shell 脚本中只读取一个字符

Posted

技术标签:

【中文标题】如何在 shell 脚本中只读取一个字符【英文标题】:How to read just a single character in shell script 【发布时间】:2012-02-02 07:10:25 【问题描述】:

我想要类似的选项,如 C 语言中的 getche()。我如何才能从命令行中读取单个字符输入?

使用read命令可以吗?

【问题讨论】:

【参考方案1】:

在 bash 中,read 可以做到:

read -n1 ans

【讨论】:

read -p "输入任意字符:" -n1 ans; echo -e "\n你输入了:$ans"【参考方案2】:

在 ksh 中你基本上可以做到:

stty raw
REPLY=$(dd bs=1 count=1 2> /dev/null)
stty -raw

【讨论】:

【参考方案3】:

read -n1 适用于 bash

stty raw 模式会阻止 ctrl-c 工作,并且会让你陷入输入循环而无路可走。手册页还说stty -raw 不能保证将您的终端返回到相同的状态。

因此,在 dtmilano's answer 的基础上使用 stty -icanon -echo 可以避免这些问题。

#/bin/ksh
## /bin/ksh,sh,zsh,...

# read_char var
read_char() 
  stty -icanon -echo
  eval "$1=\$(dd bs=1 count=1 2>/dev/null)"
  stty icanon echo


read_char char
echo "got $char"

【讨论】:

这也适用于ash(使用“BusyBox v1.10.2”测试),并且在debian上“#!/bin/sh”是dash 嗨“费斯。”。我认为我有责任通知您this question 和this meta question。而且我完全承诺要信守诺言(也许不是在我获得 75 分之后,这会使我降到 25 分,而且我可能会放弃“到处评论”,但是一旦我达到 100 分,我就会使用赏金系统) @Sam 我建议你暂时保留你的代表,因为你需要各种事情的声誉:***.com/help/privileges。我提供赏金,所以别担心。【参考方案4】:
read -n1

从输入中准确读取一个字符

echo "$REPLY"

在屏幕上打印结果

文档:https://www.computerhope.com/unix/bash/read.htm

【讨论】:

【参考方案5】:

有些人的意思是“从命令行输入”给命令一个参数,而不是从 STDIN 读取......所以请不要开枪。但我也有一个(也许不是最复杂的)STDIN 解决方案!

当使用 bash 并将数据放在变量中时,您可以使用参数扩展

$parameter:offset:length

当然,您可以在给定的参数上执行该操作($1$2$3 等)

脚本

#!/usr/bin/env bash

testdata1="1234"
testdata2="abcd"

echo $testdata1:0:1
echo $testdata2:0:1
echo $1:0:1 # argument #1 from command line

执行

$ ./test.sh foo
1
a
f

从标准输入中读取

脚本

#!/usr/bin/env bash

echo please type in your message:
read message
echo 1st char: $message:0:1

执行

$ ./test.sh 
please type in your message:
Foo
1st char: F

【讨论】:

读取单个字符更多的是在字符到达时有条件地读取、等待或执行工作,而不是假设您已经成功读取了单个字符。这会无限期地阻塞,无论是否有 char 1,交替消耗它可以消耗的所有内容并等待更多,直到它消耗一些分隔符。它会丢弃分隔符,它可能是换行符、EOF 或您尝试读取的第一个字符(在这种情况下长度为 0。)在某些情况下有效,但是...警告购买者。

以上是关于如何在 shell 脚本中只读取一个字符的主要内容,如果未能解决你的问题,请参考以下文章

Shell脚本:转义序列字符在检索带有转义序列的变量值时如何表现?

Linux:用shell如何实现读取一个字符串的第n个字符呢

shell脚本里,如何删除变量的最后一个字符?

shell脚本里,如何删除变量的最后一个字符?

如何在Shell脚本中逐行读取文件

ffmpeg在shell循环中只执行一次问题