sudo问题 - 没有获得适当的权限

时间:2017-12-20 14:02:47

标签: bash apache

我有一个bash脚本,它将登录到远程设备并复制文件。如果以用户(支持)身份登录或运行\

,它可以从命令行完美运行
sudo -u support -i '/opt/IIS/getScreenShot' <parameter>

支持用户在每台设备上都设置了密钥,因此不会在getScreenShot bash脚本的scp命令中询问密码。

我现在需要这个脚本能够被Apache调用/运行。我有一个执行以下操作的PHP脚本:

$output = shell_exec("sudo -u support -i '$command' $serial");

其中$command/opt/IIS/getScreenShot

该命令将开始运行(输出回浏览器)。如果通过Apache服务器调用bash脚本中的[ ! -d /tmp/$1 ];mkdir -p /tmp/$1等命令似乎没有执行,我不确定原因。

我原本以为sudo命令会像支持用户一样运行它,就像从命令行那样,但它不是。最终我需要/opt/IIS/getScreenShot能够从命令行和Apache调用运行。有什么建议吗?

编辑:

sudoers entry:

apache ALL=(ALL) NOPASSWD: ALL

/ opt / IIS / getScreenShot将在浏览器中显示echo语句时运行。只是脚本中的某些命令不会。 getScreenShot是:

set -e
#set -x
#Check runnable
if [ $# -lt 1 ] ; then #Check there is enough command line parameters.
    echo "Usage: $0 [<Serial#> | <Socket#>] "
    echo "      Example:  $0 GESC637005W1 "
    exit 1
fi

_socket=$(/opt/Allure/socketdata "$1" |awk -F '[(/: ]'+ '{print $10}')
#echo "socket $_socket"
if [ $_socket = "400" ];
then
   echo "400 Serial number not found"
   exit 400
fi
echo "Checking for dir /tmp/$1"
if [ ! -d /tmp/$1 ]; then
  echo "mkdir -p /tmp/$1"
  mkdir -p /tmp/$1;
fi
echo "test"
echo "scp -P$_socket support@localhost:/srv/samba/share/clarity-client/client-apps/digital-poster/screens/screenshot.png /tmp/$1/screenshot.png"
scp -P$_socket support@localhost:/srv/samba/share/clarity-client/client-apps/digital-poster/screens/screenshot.png /tmp/$1/screenshot.png
return=$?
if [ $return -ne 0 ];
then
   echo "401 scp1 failed $return"
   exit 401
fi
echo "test2"
scp /tmp/$1/screenshot.png support@172.24.16.37:/opt/digital_media/dm_content/screenshots/$1.png
return=$?
if [ $return -ne 0 ];
then
   echo "402 scp2 failed $return"
fi

快速更新以澄清我的实际问题。该脚本将实际运行,并且参数将正确传递给它。问题是某些命令&#39;在脚本中将无法正常运行,它似乎主要与测试/创建目录有关。如果目录不存在,则测试&#39;因为它不起作用。另外,如果我删除测试但是直接发出mkdir命令(在确定目录不存在之后 - 或者删除它是否存在),mkdir会显示错误:mkdir:无法创建目录&#39; / tmp / GESC637005UH&# 39;:文件存在。我直接检查了目录,但它不在那里。我已经在系统上运行了locate命令而无法找到它,所以我不确定为什么mkdir命令认为它在那里 - 并且也可能解释为什么测试&#39;似乎“失败”#39; (即它认为它存在)。

1 个答案:

答案 0 :(得分:0)

这是尝试重构您的脚本。我已经在线添加了一些评论,但这里的主要内容是使用mktemp使用保证唯一的文件,并在完成trap后清理它。其他一些小的评论:

  • 退出代码的范围是0-255,所以我从你的减去了200。
  • 应将诊断消息发送到标准错误。
  • if和shell的其他流控制语句的目的是正好来运行命令并检查其结果代码。您应该很少需要在条件中明确检查$?(例如,将其包含在诊断消息中,当然显然是有用的)。

我删除了您的评论并添加了一些我自己的评论,这些评论可能无法保留在生产脚本中。

#!/bin/sh

set -e

if [ $# -lt 1 ] ; then
    # >&2 sends diagnostics to standard error
    echo "Usage: $0 [<Serial#> | <Socket#>] " >&2
    echo "      Example:  $0 GESC637005W1 " >&2
    exit 1
fi

# Encapsulate error exit in a convenient function
die () {
    rc=$1
    shift
    # include $0 in all diagnostic messages
    echo "$0: $@" >&2
    exit "$rc"
}

_socket="$(/opt/Allure/socketdata "$1" |awk -F '[(/: ]'+ '{print $10}')"
[ $_socket = "400" ] || die 200 "Serial number $1 not found (socket $_socket)"

# Create a temporary file for this script
t=$(mktemp -t screenshot.XXXXXXXXXX) || exit
# Remove the temporary file on regular or error exit or signal
trap 'rm -f $t' EXIT ERROR HUP INT TERM

scp -P$_socket support@localhost:/srv/samba/share/clarity-client/client-apps/digital-poster/screens/screenshot.png "$t" ||
die 201 "401 scp1 failed $?"

scp "$t" support@172.24.16.37:/opt/digital_media/dm_content/screenshots/"$1".png ||
die 202 "402 scp2 failed $?"

separate Stack Overflow question

中更详细地解释了die功能

foo || bar只是

的便捷简写
if foo; then
    : nothing here
else
    bar
fi

您可以几乎等同地说if ! foo; then bar; fi但如果foo未成功运行,则会丢失失败退出代码。 (同样,foo && bar相当于if foo; then bar; fi