管理bash中csv文件中的Unix权限读取动态字段

时间:2019-03-20 13:33:18

标签: bash shell csv

我目前受制于bash脚本,该脚本应该能够在处理部分的末尾管理文件和目录的权限。

实际上我有4个组成部分:

  • 主脚本,该脚本源.conf文件和lib(.sh),进行处理,并以.csv文件作为参数结尾调用函数“ ApplyPermissionFromCSVFile”,以确保正确设置权限。此功能应处理用于管理文件权限的工作
  • 一个名为“ permission_lib.sh”的脚本,其中包含一些功能,其中包括“ ApplyPermissionFromCSVFile”。该脚本是在主脚本开始处采购的。
  • 一个.conf文件,其中包含一些定义为变量的路径,该路径在主脚本的开头是SOURCED
  • 一个.csv文件,其中包含由ApplyPermissionFromCSVFile函数读取的文件和目录的路径(包括conf文件中定义的变量的“动态路径”)。

此刻,主脚本可以正确运行,能够同时获取conf文件和lib文件,但是当我在“ ApplyPermissionFromCSVFile”中放置一些调试点时,bash似乎无法解释“动态路径”。 / p>

主脚本摘录:

######################################### 
includes 
##################################################

# this section can _almost_ be copied as-is ;-)

nameOfThisScript=$(basename "${BASH_SOURCE[0]}")
directoryOfThisScript="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"


configFile="$directoryOfThisScript/$nameOfThisScript.conf"
functionsFile="$directoryOfThisScript/safeScriptsFunctions.sh"
permissionLib="$directoryOfThisScript/permission_lib.sh"

permissionFile="$directoryOfThisScript/$nameOfThisScript.permissionFile.csv"

for fileToSource in "$configFile" "$functionsFile" "$permissionLib"; do
        source "$fileToSource" 2>/dev/null || {
                echo "File '$fileToSource' not found"
                exit 1
                }
done
#Main Loop to read CSV File is called in permissionLib.sh
ApplyPermissionFromCSVFile $permissionFile

conf文件的提取(例如,实际文件名已替换):

totovariable="/usr/local"
tatavariable="$totovariable/bin"

csv文件的提取:

$totovariable;someuser;somegroup;0600
$tatavariable;someuser;somegroup;0600

许可库文件的提取:

function ApplyPermissionFromCSVFile {
        local csvFileName="$1"
        local fieldNumberFileName=1
        local fieldNumberOwner=2
        local fieldNumberGroupOwner=3
        local fieldNumberPermissions=4

        while read csvLine
        do
                fileName=$(getFieldFromCsvLine "$fieldNumberFileName" "$csvLine")
                fileOwner=$(getFieldFromCsvLine "$fieldNumberOwner" "$csvLine")
                fileGroupOwner=$(getFieldFromCsvLine "$fieldNumberGroupOwner" "$csvLine")
                filePermissions=$(getFieldFromCsvLine "$fieldNumberPermissions" "$csvLine")
                permissionArray[0,0]="$fileName|$fileOwner|$fileGroupOwner|$filePermissions"
                echo "${permissionArray[0,0]}"
        done < "$csvFileName"
}

getFieldFromCsvLine() {
        csvFieldSeparator=';'
        fieldNumber="$1"
        csvLine="$2"
        echo "$csvLine" | cut -d "$csvFieldSeparator" -f "$fieldNumber"
}

不必担心循环在每次迭代时都会覆盖值,这不是目的(而是可选的答案:p)。

哪个输出结果:

$totovariable|someuser|somegroup|0600
$tatavariable|someuser|somegroup|0600

Changing owner to someuser:somegroup for file $tatavariable
chown: cannot access '$tatavariable': No such file or directory
Changing permissions to 0600 for file $tatavariable
chmod: cannot access '$tatavariable': No such file or directory

经过一些研究调查,看起来很正常:

  • conf文件已被保存(通过主脚本)
  • lib文件已存储(通过主脚本)
  • csv文件不是源文件,而是已读取(通过lib中的函数)。因此bash将变量内容视为“纯字符串”,而不是变量

问题是,我无法清楚地知道如何以及在何处将“ pure-string”变量替换为其值(在.conf文件中定义并由主脚本提供):在主脚本级别?在lib级别具有全局变量?

我发现的实际解决方案:

  • 替代品
  • 使用eval

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

使用的解决方案:

fileName=eval echo "$fileName"

由于.csv文件中的路径可能包含“ $”符号,因此Bash参数扩展在每种情况下都无法正常工作。

示例: 具有以下csv内容:

$tatavariable;someuser;somegroup;0600
$totovariable/thisotherfile.txt;someuser;somegroup;0660
$totovariable;someuser;somegroup;0600
/home/someuser/lolzy.txt;someuser;somegroup;0666

以及以下conf文件:

totovariable="/home/someuser/fack"
tatavariable="$totovariable/thisfile.txt"

以下bash代码(基于eval,在大多数情况下不强烈建议使用)在每种情况下(无论是否包含$符号)都适用:

#!/bin/bash

#########################
# Function
#########################

getFieldFromCsvLine() {
        local csvFieldSeparator=';'
        local fieldNumber="$1"
        local csvLine="$2"
        echo "$csvLine" | cut -d "$csvFieldSeparator" -f "$fieldNumber"
}

#########################
#Core Script
#########################

source configFile.conf

csvFileName="permissionFile.csv"
fieldNumberFileName=1
fieldNumberOwner=2
fieldNumberGroupOwner=3
fieldNumberPermissions=4

while read csvLine
do
        fileName=$(getFieldFromCsvLine "$fieldNumberFileName" "$csvLine")
        fileOwner=$(getFieldFromCsvLine "$fieldNumberOwner" "$csvLine")
        fileGroupOwner=$(getFieldFromCsvLine "$fieldNumberGroupOwner" "$csvLine")
        filePermissions=$(getFieldFromCsvLine "$fieldNumberPermissions" "$csvLine")

        #Managing Variables used as 'Dynamic path'
        fileName=$(eval echo "$fileName")
        echo "Content of \$fileName is $fileName"

done < "$csvFileName"

结果:

[someuser@SAFEsandbox:~]$ ./simpletest.sh
Content of $fileName is /home/someuser/fack/thisfile.txt
Content of $fileName is /home/someuser/fack/thisotherfile.txt
Content of $fileName is /home/someuser/fack
Content of $fileName is /home/someuser/lolzy.txt

以下bash代码(基于bash参数扩展)将引发错误:

#!/bin/bash

#########################
# Function
#########################

getFieldFromCsvLine() {
        local csvFieldSeparator=';'
        local fieldNumber="$1"
        local csvLine="$2"
        echo "$csvLine" | cut -d "$csvFieldSeparator" -f "$fieldNumber"
}

#########################
#Core Script
#########################

source configFile.conf

csvFileName="permissionFile.csv"
fieldNumberFileName=1
fieldNumberOwner=2
fieldNumberGroupOwner=3
fieldNumberPermissions=4

while read csvLine
do
        fileName=$(getFieldFromCsvLine "$fieldNumberFileName" "$csvLine")
        fileOwner=$(getFieldFromCsvLine "$fieldNumberOwner" "$csvLine")
        fileGroupOwner=$(getFieldFromCsvLine "$fieldNumberGroupOwner" "$csvLine")
        filePermissions=$(getFieldFromCsvLine "$fieldNumberPermissions" "$csvLine")

        #Managing Variables used as 'Dynamic path'
        fileName=${!fileName}
        echo "Content of \$fileName is $fileName"

done < "$csvFileName"

.csv包含$符号的行为示例:

[someuser@SAFEsandbox:~]$ ./simpletest.sh
./simpletest.sh: line 35: $tatavariable: bad substitution

删除.csv文件中的$符号时的行为示例,但其中仍然存在增量路径概念:

[someuser@SAFEsandbox:~]$ ./simpletest.sh
Content of $fileName is /home/someuser/fack/thisfile.txt
./simpletest.sh: line 35: totovariable/thisotherfile.txt: bad substitution

在这里使用bash参数扩展(大多数情况下建议这样做)并不容易,因为它会强制在脚本中管理2种情况:

  • 包含前导$或服务器$的路径(受污染的变量路径)
  • 不包含前导$或服务器$的路径(受污染的变量路径)

致谢