在Linux中读取用户输入

在Linux中读取用户输入

我编写了一个脚本,用于根据月份列出文件,用户读取该文件的方式如下:-

echo "Enter Month"
read month
ls -al | awk '$6 == "$month" {print}'

我给用户输入的是 Aug,但我没有得到任何结果。但是当我写

ls -al | awk '$6 == "Aug" {print}'

我得到了准确的结果。我做错了什么吗?请帮忙

答案1

最主要的是:变量名在单引号内不展开。这是“更好的”(即错误较少的)一行:

ls -al              | awk '$6 == "'"$month"'" {print}'
# this is in single quotes ^^^^^^^          ^^^^^^^^^

但:

  1. 但在某些地区这仍可能会失败。LC_ALL=C预先设定或许如此。
  2. 使用 ,$month你可以将(几乎?)任何东西注入awk。有更好的方法在 中使用变量awk-v选项应该更安全(感谢user000001指出这一点)。
  3. 你不应该解析输出ls首先。

正确的解决方案可能是使用findstat。以下代码可能不是最快的解决方案,但它更强大,因为:

  • 丢弃$month与预定义值不匹配的值,
  • 使用find而不是解析ls

代码:

#!/bin/sh
echo "Enter Month"
read month
case "$month" in
  1|01|Jan|jan|January|january)   monthN=01;;
  2|02|Feb|feb|February|february) monthN=02;;
# ...
  10|Oct|oct|October|october)     monthN=10;;
# ...
  *) echo Error! >&2; exit 1;;
esac
find ./ -maxdepth 1 -exec sh -c '[ `stat -c %y "$1" | cut -c 6-7` = "$2" ]' sh {} "$monthN" \; -ls

我在 Debian 上测试过;它可能不是超级可移植的。但它展示了一般的方法。

最后一行针对当前目录中的每个对象(包括./其自身)调用一个单独的 shell。此 shell 用于stat获取 mtime 信息,然后cut从中提取两位数的月份数。[ ... ]将结果与所选月份数进行比较。如果此测试成功,则对对象find执行其自身的测试(您可以使用或代替)。ls-print-print0

请注意,这永远不会返回../。另一方面,find允许您使用其他测试(如-type f),因此这种方法非常灵活。

相关内容