我最近有一次编写 shell 脚本的经历,该脚本通过消耗所有资源使服务器崩溃(并损坏了分区)。它连接到一个 cron 作业,运行时间似乎比执行之间的间隔时间更长,随着时间的推移,滚雪球失控。
现在,我已经修改了它以记录其运行状态,并且不会同时运行多次。我的问题是:还有其他简单的方法可以保护脚本免受伤害吗?是否有一个标准的脚本应该做的事情列表,以确保正常运行、不消耗太多资源、优雅地失败、提醒正确的人等?
基本上:我应该避免哪些其他陷阱?
我有一个目录结构(示例数据),我想从 Chef 配方中复制它。似乎唯一的方法是显式创建每个单独的目录和文件:
directory "/mnt/data/experiment1/dataset1" do
recursive true
only_if { node.chef_environment == "dev" }
end
directory "/mnt/data/experiment1/dataset2" do
recursive true
only_if { node.chef_environment == "dev" }
end
directory "/mnt/data/experiment2/dataset1" do
recursive true
only_if { node.chef_environment == "dev" }
end
directory "/mnt/data/experiment1/dataset2" do
recursive true
only_if { node.chef_environment == "dev" }
end
cookbook_file "/mnt/data/experiment1/dataset1/testfile1.txt" do
owner "atom"
group "atom"
mode "0644"
source "sampledata/experiment1/dataset1/testfile1.txt"
only_if { node.chef_environment == "dev"}
end
...
Run Code Online (Sandbox Code Playgroud)
有没有办法简单地从食谱中递归复制整个目录结构?在配方中指定每个文件的名称似乎是多余且容易出错的(即,如果我们将一个文件添加到树中但忘记在配方中引用它,它将不会被复制。)
我想一个 hack 解决方法是找出所有厨师文件被复制到目标机器上的位置并执行一个cp -r但是有更干净的东西吗?
还是我以错误的方式解决这个问题?
当我需要在低重要性服务器上启动后台进程时,我倾向于使用 nohup:
nohup ./server.sh &
Run Code Online (Sandbox Code Playgroud)
大多数同事似乎更喜欢屏幕:
screen -D -R mydaemon
./mydaemon.sh
^A ^D
Run Code Online (Sandbox Code Playgroud)
这两种方法的效果有什么主要区别吗?以一种方式或另一种方式有什么好处?
假设您有一个标准的 Chef 存储库,其目录如下:
cookbooks
data_bags
environments
roles
Run Code Online (Sandbox Code Playgroud)
有没有办法一次性全部上传?否则你必须这样做:
knife cookbook upload -a
knife data bag from file data_bags/*.json
knife environment from file environments/*.rb
knife role from file roles/*.json
Run Code Online (Sandbox Code Playgroud)
也许有第三方工具可以做这种事情?
我正在寻找仅用于转发几个电子邮件地址的 SMTP 服务器。两个要求:
我一直在尝试 Postfix,但我陷入了诸如Recipient address rejected: User unknown in virtual alias table和 之类的错误消息中Recipient address rejected: User unknown in local recipient table。所以我想知道是否有更简单的解决方案。
我正在尝试按如下方式设置 nginx 配置:当收到如下请求时/tile/SteveCountryVic/1/2/3.png:
http://localhost:5005/1/2/3.png/tile/SteveCountryVic/1/2/3.png这是我的配置,它不太工作:
server {
listen 80;
server_name localhost; error_log /tmp/nginx.error.log notice;
access_log /tmp/nginx.access.log;
location /tile/SteveCountryVic/ {
rewrite_log on;
#rewrite ^.*/(\d+)/(\d+)/(\d+).*$ /$1/$2/$3.png break;
proxy_intercept_errors on;
error_page 404 = @dynamiccycletour;
#proxy_set_header Host $http_host;
#proxy_pass http://127.0.0.1:5005;
proxy_redirect /tile/SteveCountryVic/ http://localhost:5005/;
location @dynamiccycletour {
rewrite_log on;
#rewrite ^(\d+)/(\d+)/(\d+).*$ /tile/SteveCountryVic/$1/$2/$3.png break;
proxy_pass http://115.x.x.x:20008;
}
location /tile/ {
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:20008;
proxy_cache my-cache;
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
}
...
Run Code Online (Sandbox Code Playgroud)
在此配置中,所有请求似乎都被重定向到代理服务器,但最终会提供图像。此外,错误日志包含以下几行:
2013/09/10 09:44:11 [error] …Run Code Online (Sandbox Code Playgroud) 假设您有目录 ~/mytool 软链接到 /usr/local/mytool。然后cd mytool将当前目录保留为 ~/mytool,这可能会导致脚本行为不正确。有没有办法避免这种行为?
通过一些谷歌搜索,我发现您可以按如下方式实现:
cd $1 ; cd `pwd -P`
Run Code Online (Sandbox Code Playgroud)
没有切换到'cd'吗?环境变量?
我知道(几乎?)所有 SSH 命令行参数都可以替换为 ~/.ssh/config 中的属性。但如何系统地执行此操作并不明显:页面man仅ssh松散地引用配置页面(例如,“端口转发也可以在配置文件中指定。”)。该man页面ssh_config从不引用命令行选项。
那么,是否有相应的配置参数和命令行选项的明确列表?例如,-R对应什么?
$ sudo -u fish -g fish bash
Sorry, user steve is not allowed to execute '/bin/bash' as fish:fish on myserver.
$ sudo -u fish bash
$ groups
fish
Run Code Online (Sandbox Code Playgroud)
-g 选项的用途是什么,为什么我不能使用它?RHEL 顺便说一句。
我正在运行 TileMill,它正在从本地主机监听端口 20008 和 20009。我希望 20009 只能通过端口 80 上的 nginx 访问(使用简单的身份验证)。我希望 20008 可以从外部“直接”访问。
server {
listen 80;
server_name localhost;
location / {
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:20009;
auth_basic "Restricted";
auth_basic_user_file htpasswd;
}
}
server {
listen 20008;
server_name localhost;
location / {
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:20008;
}
}
Run Code Online (Sandbox Code Playgroud)
明显的问题是 nginx 无法侦听端口 20008 - 它已被 TileMill 使用。
Restarting nginx: nginx: [emerg] bind() to 0.0.0.0:20008 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:20008 failed (98: Address already in …Run Code Online (Sandbox Code Playgroud) 我在 中设置了主机名别名.ssh/config,效果很好:
Host my-web
HostName 515.346.96.21
Run Code Online (Sandbox Code Playgroud)
所以我可以这样做:
ssh my-web
Run Code Online (Sandbox Code Playgroud)
但是在浏览器中,我仍然需要输入“ http://515.346.96.21”。能够做“ http://my-web”就太好了。
/etc/hosts除了使用动态 DNS 或编写脚本与 同步更改之外,有没有办法更广泛地使用 SSH 中的别名?我经常创建和销毁具有不同 IP 的 VM,因此我不断更新~/.ssh/config.
可能的重复:
在 shell 脚本中查找公共 IP 地址
为了在脚本中使用,能够做到这一点会很方便:
IP=`....something ....`
echo ...$IP... >> configfile
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我正在寻找网络上看到的 IP 地址。Ubuntu,如果它有所作为。很高兴安装一两个软件包。
我有一个干净的服务器,在 ~/.ssh/authorized_keys 中新生成的 RSA 密钥。
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug3: start over, passed a different list publickey,gssapi-keyex,gssapi-with-mic,password
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering public key: steve_rsa
debug3: send_pubkey_test
debug2: we sent a publickey packet, wait for reply
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug2: we did not send a packet, disable method
debug3: authmethod_lookup password
debug3: remaining preferred: ,password
debug3: authmethod_is_enabled password
debug1: Next …Run Code Online (Sandbox Code Playgroud)