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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18282929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:17:20  来源:igfitidea点击:

How to validate filename in bash script?

bashvalidationfilenames

提问by damphat

A little bit about my application:

关于我的应用程序的一点:

I am writing a small application in bash script. The application must store personal settings to home directory.

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

My settings are in the form of a key/value pair which will be stored as filename/content:

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

for example:
~/my-github-app
    ├── github-account
    ├── github-token

My current solution for adding a key/value:

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

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

What is the simplest and safe way to validate $KEY?

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

  • A built-in function?
  • A regular expression?
  • 内置函数?
  • 正则表达式?

I really need a reusable solution, not just for this application.

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

Edit:

编辑:

"validate filename" mean check string for proper filename format, accepted by OS.

“验证文件名”是指检查字符串的正确文件名格式,被操作系统接受。

  • "bob" : good filename format
  • "" : bad because filename can not be empty
  • "*" : ?
  • "/" : ?
  • "con" : ? ....
  • "bob" : 好的文件名格式
  • "" : 不好,因为文件名不能为空
  • “*”:?
  • “/”:?
  • “骗局”:?....

回答by Aleks-Daniel Jakimenko-A.

The only way to make something secure is to use a whitelist. Which means instead of blacklisting bad characters you allow good ones. The reason why blacklists will always fail is that you can't blacklist all of the weird characted, you'd always forget something. Especially if you're working with unicode strings.

确保安全的唯一方法是使用白名单。这意味着不是将坏字符列入黑名单,而是允许好的字符。黑名单总是失败的原因是你不能把所有奇怪的人物都列入黑名单,你总是会忘记一些东西。尤其是当您使用 unicode 字符串时。

Filenames could contain anything. According to wikipedia:

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

Ext4 Allowed characters in filenames: All bytes except NUL ('\0') and '/'

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

Which means that whole bash scripts could be valid filenames. So, if I were you, I would only allow a-zA-Z as valid characters. Problem solved.

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

That's how you do it:

这就是你的做法:

# 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

回答by alper

In addition to @Aleks-Daniel Jakimenko-A.'s answer, following script checks following conditions, If all conditions are set then Trueis returned:

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

  • a-z
  • A-Z
  • 0-9
  • underscore (_)
  • dash (-)
  • period (.)
  • Max length is 255
  • First character should be a character or number: {a-zor A-zor 0-9}
  • a-z
  • A-Z
  • 0-9
  • 下划线 ( _)
  • 破折号 ( -)
  • 期间 ( .)
  • 最大长度为 255
  • 第一个字符应该是一个字符或数字:{ a-zor A-zor 0-9}

myScript.sh:

我的脚本.sh:

#!/bin/bash
# To run: bash myScript.sh <myStringIs>

key=
# String's length check
val=$(echo "${#key}")
if [ $val -gt 255 ];
   then echo "False"; 
   exit
fi

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

# First character check
key=$(echo $key | cut -c1-1)
if ! [[ $key =~ ^[0-9a-zA-Z]+$ ]]; then
    echo 'False'; 
    exit
fi

echo 'True';

回答by epsilon

If you just want to check if a file already exists, use the testcommand and use it like this for your validation :

如果您只想检查文件是否已存在,请使用该test命令并像这样使用它进行验证:

if [[ ! -e "$KEY" ]]
then
    #file doet not exists
fi

回答by zigdon

What do you want to validate, just that a key doesn't contain any path info?

你想验证什么,只是一个密钥不包含任何路径信息?

KEY=$(basename $KEY) 

This would remove any parts of the KEY that are part of the path. That said, there are plenty of things the user could enter that would probably be a bad idea. Can you perhaps have a list of allowed keys, then reject anything that isn't in that list?

这将删除作为路径一部分的 KEY 的任何部分。也就是说,用户可以输入的很多东西可能是个坏主意。您能否拥有一个允许的密钥列表,然后拒绝不在该列表中的任何内容?

If you're trying to see if a file is writable, you could check if a) it exists and is writable (-w) or b) just try to write to it and check for errors.

如果您想查看文件是否可写,您可以检查 a) 它是否存在且可写 ( -w) 或 b) 尝试写入文件并检查错误。