如何在bash脚本中验证文件名?

dam*_*hat 3 validation bash filenames

关于我的应用程序:

我正在用bash脚本编写一个小应用程序.应用程序必须将个人设置存储到主目录.

我的设置采用键/值对的形式,将存储为文件名/内容:

for example:
~/my-github-app
    ??? github-account
    ??? github-token
Run Code Online (Sandbox Code Playgroud)

我目前添加键/值的解决方案:

read KEY
read VALUE
# FIXME! should check for for valid filename.
#        user can do injection hack by KEY="../../path/to/yourfile"
echo $VALUE > ~/my-github-app/$KEY
Run Code Online (Sandbox Code Playgroud)

验证$ KEY最简单,最安全的方法是什么?

  • 内置功能?
  • 正则表达式?

我真的需要一个可重用的解决方案,而不仅仅是这个应用程序.

编辑:

"validate filename"表示检查字符串的正确文件名格式,由OS接受.

  • "bob":良好的文件名格式
  • "":错误,因为filename不能为空
  • "*":?
  • "/":?
  • "骗局":?....

Ale*_*-A. 5

确保安全的唯一方法是使用白名单.这意味着不是将不良角色列入黑名单,而是允许使用好的角色.黑名单总是会失败的原因是你不能将所有奇怪的人列入黑名单,你总会忘记一些事情.特别是如果你正在使用unicode字符串.

文件名可以包含任何内容.根据维基百科:

Ext4文件名中允许的字符:除NUL('\ 0')和'/'之外的所有字节

这意味着整个bash脚本可能是有效的文件名.所以,如果我是你,我只允许a-zA-Z作为有效字符.问题解决了.

你就是这样做的:

# if [[ $key =~ [^a-zA-Z] ]]; then # or this. Whatever makes more sense to you
if ! [[ $key =~ ^[a-zA-Z]+$ ]]; then
    echo 'Wrong key. Only a-zA-Z characters are allowed' >&2 # write to stderr
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)


alp*_*per 5

除了 @Aleks-Daniel Jakimenko-A. 的回答之外,以下脚本还会检查以下条件,如果设置了所有条件,则True返回:

  • a-z
  • A-Z
  • 0-9
  • 下划线 ( _)
  • 破折号 ( -)
  • 时期 (.
  • 最大长度为 255
  • 第一个字符应该是字符或数字:{a-z或}A-z0-9

my_script.sh:

#!/bin/bash
# To run: bash my_script.sh <my_string_is>

key=$1
val=$(echo "${#key}")

if [[ $key == "" ]]; then
   echo "False";
   exit
fi

if [[ $key == "." ]] || [[ $key == ".." ]]; then
    # "." and ".." are added automatically and always exist, so you can't have a
    # file named . or .. // https://askubuntu.com/a/416508/660555
    echo "False";
    exit
fi

if [ $val -gt 255 ]; then
   # String's length check
   echo "False";
   exit
fi

if ! [[ $key =~ ^[0-9a-zA-Z._-]+$ ]]; then
    # Checks whether valid characters exist
    echo "False";
    exit
fi

_key=$(echo $key | cut -c1-1)
if ! [[ $_key =~ ^[0-9a-zA-Z.]+$ ]]; then
    # Checks the first character
    echo "False";
    exit
fi

echo "True";
Run Code Online (Sandbox Code Playgroud)