2012-01-24 81 views
34

我环顾四周寻找答案但找不到。自我删除外壳脚本

我写了一个简单的脚本来完成初始服务器设置,我希望它在完成时从根目录中删除/取消链接。我尝试了许多解决方案(例如/ bin/rm $ test.sh),但脚本似乎总是保持不变。这可能吗?以下是我的脚本。

#! /bin/bash 
cd /root/ 
wget -r -nH -np --cut-dirs=1 http://myhost.com/install/scripts/ 
rm -f index.html* *.gif */index.html* */*.gif robots.txt 
ls -al /root/ 

if [ -d /usr/local/psa ] 
    then 
     echo plesk > /root/bin/INST_SERVER_TYPE.txt 
    chmod 775 /root/bin/* 
    /root/bin/setting_server_ve.sh 
    rm -rf /root/etc | rm -rf /root/bin | rm -rf /root/log | rm -rf /root/old 
    sed -i "75s/false/true/" /etc/permissions/jail.conf 
     exit 1; 
elif [ -d /var/webmin ] 
    then 
    echo webmin > /root/bin/INST_SERVER_TYPE.txt 
    chmod 775 /root/bin/* 
    /root/bin/setting_server_ve.sh 
    rm -rf /root/etc | rm -rf /root/bin | rm -rf /root/log | rm -rf /root/old 
    sed -i "67s/false/true/" /etc/permissions/jail.conf 
     break 
    exit 1; 
else 
    echo no-gui > /root/bin/INST_SERVER_TYPE.txt 
    chmod 775 /root/bin/* 
    /root/bin/setting_server_ve.sh 
    rm -rf /root/etc | rm -rf /root/bin | rm -rf /root/log | rm -rf /root/old 
    sed -i "67s/false/true/" /etc/permissions/jail.conf 
     break 
    exit 1; 
fi 
+2

如果您打算使用自删除脚本,则必须确保在每次测试前您都有备份副本。或者你可以用'$ {RM: -/bin/rm}'替换'rm'进行测试。你的代码管道'rm'输出到下一个'rm'命令是非常奇怪的; 'rm'既不从标准输入中读取,除非它变为交互式(它不会与-rf一起),也不写入标准输出。重复是不好的。我不希望你从我的机器上的'/ root'中删除东西。另外,请检查'cd/root /'是否工作。 'cd/root/||出口1'。 –

+1

嗨乔纳森。非常感谢您的反馈。你可以说,我对这一切都很陌生。我在安装rm test.sh部分时犯了一个非常基本的错误,但现在它工作正常。还纠正了rm命令。再次感谢! – RFH

+2

为什么你需要删除这个脚本?例如,如果它是在远程主机上运行的一次性事物,则可以运行'ssh host l0b0

回答

53
rm -- "$0" 

应该做的伎俩。 $ 0是执行脚本完整路径的魔术变量。

+2

在'bash'下,似乎是这种情况('$ 0'是脚本的路径); '并非总是如此(其他shell,其他操作系统),甚至现在在每个系统上可能都不是这样。 –

+0

我的印象是,它是由posix指定的,说我不是专家。(ab)在使用'#!/ bin/sh'作为大多数主流BSD,linux,osx和solaris的解释器的脚本中非常狂野地使用'cd $(dirname $ 0)'这样的kludges,它,但我不能对一切做出承诺。 – richo

+0

谢谢。这也工作:) – RFH

15

这个工作对我来说:

#!/bin/sh 

rm test.sh 

也许你并没有真的要在 '$ test.sh' 的 '$'?

+0

它的工作!非常感谢。 – RFH

+6

哇,你真的没有试过这个? haha – justhalf

-2

为什么要删除脚本?正如其他人所说,这意味着您必须在其他地方保留副本。

建议使用“firstboot”类似的方法。只需在例如/ etc/sysconfig,如果它存在,将触发此脚本的执行。然后在脚本结尾处删除该文件。

修改脚本,使其具有必需的chkconfig标题并将其放置在/etc/init.d/中,以便在每次启动时运行它。

这样,只需重新创建触发器脚本,您就可以在稍后重新运行脚本。

希望这会有所帮助。

+17

我通常不会缩略图,但是当我这样做时,我发表评论。所以这里是:你“回答”不是解决问题的方法。一般而言,提交者为什么要做某件事,这与你无关。质疑提问者的动机是多余的,刺激的和无关紧要的。正如在这种特殊情况下一样:对于文件删除本身来说这很少见,但有时候至关重要,例如当你想运行一个卸载脚本。在这种情况下,ziesemer的答案是一个完美的解决方案。 –

+1

@TranSonHai:对不起,如果你对答案感到恼火。但我真的相信,在许多情况下,这种方法对面临类似问题的用户非常有用。 – Bram

+4

我不知道任何情况下你的方法可能是有益的。我的理解是,当你想要的时候,说出自己的东西卸载,然后你不想留下任何痕迹。创建一个外部脚本来删除东西最终会导致一个矛盾的情况,在这种情况下,您需要创建另一个外部脚本来删除该外部脚本,等等。 那么,为什么不接受上面的人提供的简单,优雅的答案,并放弃使事情变得不必要的复杂? –

3

脚本在退出时可以通过shred command作为安全删除)将其自身删除。

#!/bin/bash 

currentscript="$0" 

# Function that is called when the script exits: 
function finish { 
    echo "Securely shredding ${currentscript}"; shred -u ${currentscript}; 
} 

# Do your bashing here... 

# When your script is finished, exit with a call to the function, "finish": 
trap finish EXIT