我可以使用传统方式运行以下脚本:
cd ~ && vi script.sh [PASTE SCRIPT INSIDE] && chmod +x script.sh && ./script.sh && rm -rf script.sh
然而,如果我使用 Heredoc 执行完全相同的脚本(直接从 Bash 提示符粘贴并执行),那么该脚本将仅部分执行,并且将在结束之前中断。
例如,当我使用 Heredoc 运行以下脚本时会发生什么:
PHPmyadmin 安装界面与 CLI 融合,而 CLI 本身除了记录标准输入之外几乎失去了所有功能:
脚本(与我的 Heredoc 一起):
bash << 'EOT0'
#!/bin/bash -x
# Setup LAMP environment with enabled mod rewrite:
cd ~
apt-get install lamp-server^ -y
a2enmod rewrite
cat << EOF >> /etc/apach2/apache2.conf
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
EOF
service apache2 restart
# Setup Webmin and some dependencies:
apt-get install unzip perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python -y
wget http://prdownloads.sourceforge.net/webadmin/webmin_1.810_all.deb
dpkg --install webmin_1.810_all.deb
apt-get -f install
sed -i 's/ssl=1/ssl=0/g' /etc/webmin/miniserv.conf
/etc/init.d/webmin restart
# Cron tasks:
echo -e "\07" && echo -e "\007" # Choose Nano (2) and do ^x.
USER=benqzq
crontab -u $USER -l 2>/dev/null
cat <<- 'EOF'
0 8 * * * tar -zcvf /home/USERNAME/backups/files/www-html-$(date +\%F-\%T-).tar.gz /var/www/html
0 8 * * * find /home/USERNAME/backups/files/* -mtime +30 -exec rm {} \;
0 8 * * * mysqldump -u root -PASSWORD --all-databases > /home/USERNAME/backups/mysql/alldb_backup.sql
1 8 * * * tar -zcvf /home/USERNAME/backups/mysql/alldb_backup-$(date +\%F-\%T-).sql.tar.gz /home/USERNAME/backups/mysql/alldb_backup.sql
2 8 * * * rm /home/USER/backups/mysql/alldb_backup.sql
2 8 * * * find /home/USERNAME/backups/mysql/* -mtime +30 -exec rm {} \;
EOF
crontab -e
USER=root
# Setup PMA:
echo -e "\07" && echo -e "\007"
apt-get install phpmyadmin php-mb\string php-gettext -y
phpenmod mcrypt && phpenmod mbstring
bash -c "echo 'Include /etc/phpmyadmin/apache.conf' >> /etc/apache2/apache2.conf"
systemctl reload apache2.service
# Setup Fail2Ban:
apt-get install fail2ban -y
# Secure PMA HTTP authentication from BFAs with Fail2Ban:
cat << EOF > /etc/fail2ban/filter.d/phpmyadmin.conf
[Definition]
denied = mysql-denied|allow-denied|root-denied|empty-denied
failregex = ^<HOST> -.*(?:%(denied)s)$
ignoreregex =
EOF
cat << EOF >> /etc/fail2ban/jail.local
[phpmyadmin]
enabled = true
port = http,https
filter = phpmyadmin
logpath = /var/log/apache2/phpmyadmin_access.log
EOF
service apache2 reload
service fail2ban reload
reboot
# Comment1
# Comment2
# Comment3
# ...
EOT0
斯蒂芬·查泽拉斯的更新
答案1
你正在做的:
bash << 'EOT'
some-command-that-reads-stdin
EOT
但是some-command-that-reads-stdin
的标准输入也将是此处的文档,因为它是由bash
so 继承相同的stdin
.
你可以这样做:
bash /dev/fd/3 3<< 'EOT'
some-command-that-reads-stdin
EOT
所以 stdin 保持不变,并bash
从另一个 fd 上的此处文档获取代码。
答案2
它可能使用了错误的外壳。我会删除bash << 'EOT0'
和之间的空行#!/bin/bash -x
。
您可以添加此行来检查使用了哪个 shell:
echo $SHELL >/tmp/shell.txt
然后用一只简单的猫检查结果:
cat /tmp/shell.txt