Shell 脚本,删除文件而不给出整个名称作为参数

Shell Scripting, remove a file without giving the entire name as a parameter

假设我们有一个名为 randomfile_a434534_Frank.csv

的文件

我希望用户输入第一部分 "randomfile*" 作为参数而不是全部。我如何能够 access/say 删除这个特定文件而不指定整个文件名

以下重新提示,直到给出仅匹配单个文件的前缀。根据口味修改——如果你只想测试一次,请删除循环,如果你想从命令行获取前缀,请参考 </code>,或者在多个文件的情况下迭代 <code>"${files[@]}"如果您的意图是匹配而不是 bailing/reprompting。

#!/bin/bash
# note that the above is necessary to enable features such as arrays; shells started
# with #!/bin/sh may not provide them.

while :; do
  echo "Please enter a filename prefix:" >&2
  IFS= read -r filename

  files=( "$filename"* )
  if (( ${#files[@]} == 1 )) && [[ -e "$files" ]]; then
    echo "OK; using $files" >&2
    break
  elif [[ ! -e "$files" ]] || (( ${#files[@]} == 0 )); then
    echo "Error: No matching files found" >&2
  else
    echo "Error: More than one file matches that prefix" >&2
  fi
done

echo "Operating on file named: $files"

您可以只使用 rm "$intput"* 的用户输入(或者 -i 如果您希望用户检查哪些文件正在被删除)但要注意实际的用户输入,这可能会使您的脚本出现意外maner.

这是一个小的 shell 概念证明:

$ touch aaJKL
$ toto=aa
$ rm -i "$toto"* # thanks Charles Duffy
rm: remove regular empty file `aaJKL'? y

会发生什么?

  • 用户提供../../../path/to/sensitive/file
  • 用户提供./; <<nasty command>>; echo "并执行任意命令正如Charles所指出的,这种漏洞只发生在字符串替换before shell 执行语法解析(例如生成要传递给 system() 的字符串时,或者当 eval 用于强制执行额外的解析传递时)。
  • 用户使用符号 link 指向另一个文件

另一个提示是向用户提示一个 inode 号,并确保这个 inode 号是合法的。

例如,您可以这样做:

#!/usr/bin/env bash

echo "Choose a single file number you want to remove"
ls -i1 ./
read filenumber
if [[ $filenumber =~ ^[-+]?[0-9]+$ ]]; then
        find . -inum $filenumber -delete
else
        echo "Expect integer as an input"
fi

示例输出:

$ touch sample{1,2,3,4}
$ ./so.sh 
Choose a single file number you want to remove
1614159 sample1
1614160 sample2
1614161 sample3
1614162 sample4
fds
Expect integer as an input
$ ./so.sh 
Choose a single file number you want to remove
1614159 sample1
1614160 sample2
1614161 sample3
1614162 sample4
1614159

$ ./so.sh  # notice that sample1 was deleted
Choose a single file number you want to remove
1614160 sample2
1614161 sample3
1614162 sample4