并发访问unix中的文件

时间:2014-07-18 14:35:01

标签: shell concurrency ssh

我有一个可以在远程服务器上运行的脚本,

df_command.sh: -

#!/bin/bash

if [[ $1 == "" ]]; then
    echo -e "No Argument passed:- Showing default disk usage\n"
    df -k > /tmp/Global_df_tmp 2>&1
    cat /tmp/Global_df_tmp
else
    df -k "$1" > /tmp/Global_df_tmp 2>&1
    cat /tmp/Global_df_tmp
fi

这是我运行此脚本的方式: -

$ssh -oConnectTimeout=5 -oBatchMode=yes -l group servername 'bash -s -- /some/directory' < ./df_command.sh

这很好,并且在每个场景中都给我正确的输出,意味着如果用户通过任何有效的目录,它会给我该目录的磁盘使用情况,如果他/她通过了一些无效的目录,脚本会给我正确的错误消息。< / p>

当多个用户同时为同一服务器开始使用脚本并传递两个不同的目录时,问题就会出现

e.g

用户A: -

$ssh -oConnectTimeout=5 -oBatchMode=yes -l group servername 'bash -s -- /user_A/directory' < ./df_command.sh

用户B: -

$ssh -oConnectTimeout=5 -oBatchMode=yes -l group servername 'bash -s -- /user_B/directory' < ./df_command.sh

现在由于脚本的tmp文件是相同的(/tmp/Global_df_tmp),无论谁先启动脚本都会获得正确的输出,而第二个用户将获得与第一个用户相同的输出。

我知道一个解决方案是生成随机数并使用它而不是硬编码的tmp文件,但是如果100个用户将使用相同的脚本,那么我最终会在远程服务器上拥有大量的临时文件< / p>

还有其他想法吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

显而易见的解决方案是不对临时文件使用固定名称。一种常见的方法是在后缀中使用进程标识符,例如/tmp/Global_df_tmp.$$

此外,如果您使用的是bash,则可以$RANDOM获取随机数。

或者只需使用mktemp命令创建一个具有随机名称的临时文件。

答案 1 :(得分:0)

您可以使用标准mktemp命令生成临时文件名:

# Create a tempfile (in a BSD- and Linux-friendly way) 
my_mktemp () { 
mktemp || mktemp -t my_prefix 
} 2> /dev/null 

declare -r tempfile=$(my_mktemp) || echo "Cannot create temp file" >&2

df -k > "$tempfile" 2>&1

只是一点点解释:my_mktemp是一个bash函数(你不需要使用它,如果你在Linux上,只需使用mktemp。

declare -r tempfile=$(cmd)运行命令cmd并将其设置为名为temp file的新只读变量的值。

之后你可以使用&#34; $ tempfile&#34;引用临时文件名。