分类目录归档:cdn

fredzeng与你一起对cdn,cdn加速,cdn是什么,免费cdn,cdn公司,cdn厂商,cdn技术学习相关知识及探讨!

nginx通过自定义header属性来转发不同的服务

读取自定义header

首先,开启underscores_in_headers

解释:HTTP头部是否允许下划线。默认为off,表示HTTP头部的名称中不允许带“_”
语法:underscores_in_headers on | off;
默认:underscores_in_headers off;
配置块:http、server

一、背景

因为需要上线灰度发布,只要nginx接收到头部为:

wx_unionid:123456

就会跳转到另外一个url,比如:

127.0.0.1:8080

通过配置nginx 匹配请求头wx_unionid 来转发到灰度环境。 核心:客户端自定义的http header,在nginx的配置文件里能直接读取到。 条件:header必须用减号“-”分隔单词,nginx里面会转换为对应的下划线“_”连接的小写单词。

二、修改Nginx配置

安装nginx

apt-get install -y nginx

编辑主页

cd /etc/nginx/sites-enabled
vim home.conf

内容如下:

upstream wx {
    server 127.0.0.1:8080;
}

server {  
    listen 8008;
    server_name localhost;

    root html;
    index index.html;

    charset utf-8;
    underscores_in_headers on;
    location / {
        #测试header转发 
        if ($http_wx_unionid = "123456") {
            proxy_pass http://wx;
        }  
    }  
}

参数配置说明

underscores_in_headers on:nginx是支持读取非nginx标准的用户自定义header的,但是需要在http或者server下开启header的下划线支持: 比如我们自定义header为wx_unionid,获取该header时需要这样:$http_wx_unionid(一律采用小写,而且前面多了个http_)

如果需要把自定义header传递到下一个nginx: 1.如果是在nginx中自定义采用proxy_set_header X_CUSTOM_HEADER $http_host; 2.如果是在用户请求时自定义的header,例如curl –head -H “X_CUSTOM_HEADER: foo” http://domain.com/api/test,则需要通过proxy_pass_header X_CUSTOM_HEADER来传递

编辑调整页

vim wx.conf

内容如下:

server {
    listen 8080;
    server_name localhost;

    root /var/www/html;
    index wx.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

增加测试页面

vim /var/www/html/wx.html

内容如下:

<h1>微信小程序测试平台</h1>

三、测试结果

加自定义头部

root@ubuntu:~# curl -v -H 'wx_unionid:123456' 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 07:49:46 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 37
< Connection: keep-alive
< Last-Modified: Mon, 29 Jul 2019 06:23:49 GMT
< ETag: "5d3e90f5-25"
< Accept-Ranges: bytes
< 
<h1>微信小程序测试平台</h1>
* Connection #0 to host 127.0.0.1 left intact

不加头部

root@ubuntu:~# curl -v 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 07:50:13 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 612
< Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
< Connection: keep-alive
< ETag: "5890a6b7-264"
< Accept-Ranges: bytes
< 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact

四、匹配多条件

现在又多了一个需求,需要对客户端ip为:192.168.0.45,同时也增加自定义头部wx_unionid:123456,才会转发,否则不做转发。

nginx的配置中不支持if条件的逻辑与&& 逻辑或|| 运算 ,而且不支持if的嵌套语法,否则会报下面的错误:nginx: [emerg] invalid condition。

我们可以用变量的方式来间接实现。

要实现的语句:

if ($remote_addr ~* "192.168.0.45" && $http_wx_unionid = "123456"){
    proxy_pass http://wx;
}

如果按照这样来配置,就会报nginx: [emerg] invalid condition错误。

如下:

nginx: [emerg] invalid condition "$http_wx_unionid" in /etc/nginx/sites-enabled/home.conf:16
nginx: configuration file /etc/nginx/nginx.conf test failed

可以这么来实现,如下所示:

upstream wx {
    server 127.0.0.1:8080;
}

server {  
    listen 8008;
    server_name localhost;

    root html;
    index index.html;

    charset utf-8;
    underscores_in_headers on;
    location / {
        #测试header转发
        # 标志位
        set $flag 0;
        if ($remote_addr ~* "192.168.0.45"){
             # 末尾追加1,此时$flag=01
             set $flag "${flag}1";
        }
        if ($http_wx_unionid = "123456"){
            # 末尾追加1,此时$flag=011
            set $flag "${flag}1";
        }
        # 当为011时,表示条件都匹配
        if ($flag = "011") {
            proxy_pass http://wx;
        }
    }  
}

重新加载配置

nginx -s reload

再次使用本机测试,增加头部

root@ubuntu:~# curl -v -H 'wx_unionid:123456' 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 08:01:30 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 612
< Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
< Connection: keep-alive
< ETag: "5890a6b7-264"
< Accept-Ranges: bytes
< 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact

登录到192.168.0.45,增加头部测试

root@docker-reg:~# curl -v -H 'wx_unionid:123456' 192.168.0.162:8008
* Rebuilt URL to: 192.168.0.162:8008/
*   Trying 192.168.0.162...
* Connected to 192.168.0.162 (192.168.0.162) port 8008 (#0)
> GET / HTTP/1.1
> Host: 192.168.0.162:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 08:02:01 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 37
< Connection: keep-alive
< Last-Modified: Mon, 29 Jul 2019 06:23:49 GMT
< ETag: "5d3e90f5-25"
< Accept-Ranges: bytes
< 
<h1>微信小程序测试平台</h1>
* Connection #0 to host 192.168.0.162 left intact

CentOS 7源码安装Redis 6.0及自启动

Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。当下非常流行,使用非常广泛,这篇文章记录下CentOS 7源码安装Redis服务的方法。

安装Redis

先执行下面的命令,安装一大堆依赖:

#安装依赖
yum -y install cpp binutils glibc glibc-kernheaders glibc-common glibc-devel gcc make
#升级gcc
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
scl enable devtoolset-9 bash

写这篇文章的时候,Redis最新稳定版为6.0,随着时间推移,版本会发生变化,请前往Redis官方:https://redis.io/download下载最新版本。

#下载Redis
wget https://download.redis.io/releases/redis-6.0.9.tar.gz
#解压Redis
tar xzf redis-6.0.9.tar.gz
#进入Redis目录
cd redis-6.0.9
#编译
make

编译成功后,Redis服务二进制文件位于src/redis-server,直接输入这个路径即可运行Redis服务,不过运行后是在前台运行,一旦结束或窗口关闭,Redis服务也随之停止。

运行Redis

为了方便后期管理与维护,可以将Redis src放到特定目录下,比如mv src/ /usr/local/redis

同时可以将redis-6.0.9目录下的redis.conf也复制一份:

cp redis.conf /etc

默认情况下,Redis是前台运行,如果需要后台运行,需要修改redis.conf配置文件,将

daemonize no

修改为:

daemonize yes

然后输入命令:/usr/local/redis/redis-server /etc/redis.conf重新启动Redis服务,这个时候就是保持后台运行了,通过ps命令可看到进程:

[root@hecs-centos-7 ~]# ps -ef|grep 'redis'
root     10217     1  0 22:00 ?        00:00:00 /usr/local/redis/redis-server 127.0.0.1:6379

设置环境变量

每次都输入Redis绝对路径来运行,难免还是有些不方便,我们可以将Redis路径加入到Linux环境变量,在/etc/profile这个文件底部追加:

export PATH=$PATH:/usr/local/redis

再输入命令source /etc/profile使其生效,这样我们就可以直接执行redis命令,而不用输入完整路径了。比如:

[root@hecs-centos-7 ~]# redis-server -v
Redis server v=6.0.9 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=ef93b08070de4db5

Redis客户端

通过上面编译后,Redis自带了一个命令行客户端redis-cli,输入下面的命令可检测Redis是否正常运行。

[root@hecs-centos-7 ~]# /usr/local/redis/redis-cli 
127.0.0.1:6379> ping
PONG

注册为Systemd服务

如果需要将Redis设置为开启启动,我们可以将redis注册为Systemd服务,方便日后管理。首先创建一个服务文件:vi /etc/systemd/system/redis.service,内容如下:

[Unit]
Description=Redis Server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/redis/redis-server /etc/redis.conf

[Install]
WantedBy=multi-user.target

然后输入systemctl daemon-reload重新加载服务,接下来就可以使用systemctl命令来管理了:

#启动redis
systemctl start redis
#停止redis
systemctl stop redis
#开机启动
systemctl enable redis

redis批量删除key 远程批量删除key

一、遇到的问题

  在开发的过程中,经常会遇到要批量删除某种规则的key,如缓存的课程数据“course-课程uid”,其中课程uid是变量,我们需要删除”course-*”这一类的数据,但是这里就坑了,redis有提供批量查询一类key的命令keys,但是没有提供批量删除某种类型key的命令。

二、解决方案

  先看看我们怎么解决。

1、先进入redis的客户端

cd redis所在目录/src
./redis-cli

2、初始化数据,模拟数据

复制代码
127.0.0.1:6379> set course-1 1
OK
127.0.0.1:6379> set course-2 2
OK
127.0.0.1:6379> set course-3 3
OK
复制代码

3、通过keys命令可以看到,现在有上面的三个key

127.0.0.1:6379> keys  course-*
1) "course-3"
2) "course-2"
3) "course-1"

4、退出redis的客户端

127.0.0.1:6379> exit

5.1、本地批量删除key

./redis-cli keys "course-*" | xargs ./redis-cli del

此处刚刚 course-*  相关的3个key已经被删除了

原理解析:

  先通过redis客户端执行了keys命令,模糊搜索出所有的key,通过xargs命令,将前面查询出来的key作为后面redis的del命令的输入

最终执行的结果可以理解成

 1、模糊查询

keys "course-*" 

  查询出上面的course-1 course-2 course-3 这三个key

2、执行删除key

  del的三个key来自前面的keys查询

del course-1 course-2  course-3    

5.2、远程批量删除key

  经常我们开发的时候,redis都是公用的,可能redis不在本地我们可以通过redis客户端远程进行删除

./redis-cli -h redis所在服务器ip -p 端口 keys "course-*" |xargs ./redis-cli -h redis所在服务器ip -p 端口 del

三、补充知识

1、远程某台机子的redis

  以下实例演示了如何连接到主机为 127.0.0.1,端口为 6379 ,密码为 mypass 的 redis 服务上。

redis-cli -h 127.0.0.1 -p 6379 -a "mypass"

2、xargs命令

xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。 详情课件 http://man.linuxde.net/xargs

转自:https://www.cnblogs.com/0201zcr/p/9647787.html

curl: (35) SSL connect error

linux 命令行curl 访问https出现如下error:

rpm –import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

curl: (35) SSL connect error
error: https://www.elrepo.org/RPM-GPG-KEY-elrepo.org: import read failed(2).

* Closing connection #0

* SSL connect error

curl: (35) SSL connect error

解决方法:

yum update -y nss curl libcurl ca-certificates

yum update -y nss curl libcurl ca-certificates

Loaded plugins: fastestmirror
Setting up Update Process
Loading mirror speeds from cached hostfile
Resolving Dependencies
There are unfinished transactions remaining. You might consider running yum-complete-transaction first to finish them.
^C–> Running transaction check
—> Package ca-certificates.noarch 0:2017.2.14-65.0.1.el6_9 will be updated
[root@10-13-72-98 vhost]# yum update -y nss curl libcurl ca-certificates

Loaded plugins: fastestmirror
Setting up Update Process
Loading mirror speeds from cached hostfile
Resolving Dependencies
There are unfinished transactions remaining. You might consider running yum-complete-transaction first to finish them.
–> Running transaction check
—> Package ca-certificates.noarch 0:2017.2.14-65.0.1.el6_9 will be updated
—> Package ca-certificates.noarch 0:2020.2.41-65.1.el6_10 will be an update
—> Package curl.x86_64 0:7.19.7-53.el6_9 will be updated
—> Package curl.x86_64 0:7.19.7-54.el6_10 will be an update
—> Package libcurl.x86_64 0:7.19.7-53.el6_9 will be updated
–> Processing Dependency: libcurl = 7.19.7-53.el6_9 for package: libcurl-devel-7.19.7-53.el6_9.x86_64
—> Package libcurl.x86_64 0:7.19.7-54.el6_10 will be an update
–> Running transaction check
—> Package libcurl-devel.x86_64 0:7.19.7-53.el6_9 will be updated
—> Package libcurl-devel.x86_64 0:7.19.7-54.el6_10 will be an update
–> Finished Dependency Resolution

Dependencies Resolved

======================================================================================================================================================

Package Arch Version Repository Size

Updating:
ca-certificates noarch 2020.2.41-65.1.el6_10 updates 908 k
curl x86_64 7.19.7-54.el6_10 updates 198 k
libcurl x86_64 7.19.7-54.el6_10 updates 170 k
Updating for dependencies:
libcurl-devel x86_64 7.19.7-54.el6_10 updates 247 k

Transaction Summary

Upgrade 4 Package(s)

Total download size: 1.5 M
Downloading Packages:
(1/4): ca-certificates-2020.2.41-65.1.el6_10.noarch.rpm | 908 kB 00:00
(2/4): curl-7.19.7-54.el6_10.x86_64.rpm | 198 kB 00:00
(3/4): libcurl-7.19.7-54.el6_10.x86_64.rpm | 170 kB 00:00

(4/4): libcurl-devel-7.19.7-54.el6_10.x86_64.rpm | 247 kB 00:00

Total 18 MB/s | 1.5 MB 00:00
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Updating : libcurl-7.19.7-54.el6_10.x86_64 1/8
Updating : curl-7.19.7-54.el6_10.x86_64 2/8
Updating : libcurl-devel-7.19.7-54.el6_10.x86_64 3/8
Updating : ca-certificates-2020.2.41-65.1.el6_10.noarch 4/8
Cleanup : libcurl-devel-7.19.7-53.el6_9.x86_64 5/8
Cleanup : curl-7.19.7-53.el6_9.x86_64 6/8
Cleanup : ca-certificates-2017.2.14-65.0.1.el6_9.noarch 7/8
Cleanup : libcurl-7.19.7-53.el6_9.x86_64 8/8
Verifying : curl-7.19.7-54.el6_10.x86_64 1/8
Verifying : libcurl-devel-7.19.7-54.el6_10.x86_64 2/8
Verifying : libcurl-7.19.7-54.el6_10.x86_64 3/8
Verifying : ca-certificates-2020.2.41-65.1.el6_10.noarch 4/8
Verifying : curl-7.19.7-53.el6_9.x86_64 5/8
Verifying : libcurl-devel-7.19.7-53.el6_9.x86_64 6/8
Verifying : libcurl-7.19.7-53.el6_9.x86_64 7/8
Verifying : ca-certificates-2017.2.14-65.0.1.el6_9.noarch 8/8

Updated:
ca-certificates.noarch 0:2020.2.41-65.1.el6_10 curl.x86_64 0:7.19.7-54.el6_10 libcurl.x86_64 0:7.19.7-54.el6_10

Dependency Updated:
libcurl-devel.x86_64 0:7.19.7-54.el6_10

Complete!

广电DNS地址

广电网DNS地址陕西210.87.141.250  陕西省西安市//汉中市广电网180.1677%
广电网DNS地址天津211.148.160.209  天津市/广电网10.0093%
广电网DNS地址四川60.255.80.19  四川省/广电网10.0093%
广电网DNS地址福建203.190.96.2  福建省福州市/广电网10.0093%
广电网DNS地址江苏211.167.132.29  江苏省苏州市/广电网10.0093%
广电网DNS地址四川60.255.80.18  四川省/广电网10.0093%
广电网DNS地址山东210.77.192.88  山东省济南市/广电网10.0093%

Centos6利用rpm升级OpenSSH到openssh-8.1p1版本

CentOS6的rpm升级包进行OpenSSH到openssh-8.1p1版本分享。

下载:

wget https://cikeblog.com/s/openssh8.1-6.tar.gz
tar -zxvf openssh8.1-6.tar.gz

安装方法一:

rpm -Uvh *.rpm

安装方法二(此方法会自动处理依懒关系):

yum install ./*.rpm

安装后会如下提示:

[root@test ~]# rpm -Uvh *.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:openssh-8.1p1-1.el7              ################################# [ 14%]
   2:openssh-clients-8.1p1-1.el7      ################################# [ 29%]
   3:openssh-server-8.1p1-1.el7       ################################# [ 43%]
   4:openssh-debuginfo-8.1p1-1.el7    ################################# [ 57%]
[root@test ~]# ssh -V
OpenSSH_8.1p1, OpenSSL 1.0.1e-fips 11 Feb 2013
[root@768 ~]#

至此,升级完成,因为OPENSSH升级后,/etc/ssh/sshd_config会还原至默认状态,我们需要进行相应配置:

cd /etc/ssh/
chmod 400 ssh_host_ecdsa_key ssh_host_ed25519_key ssh_host_rsa_key
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
echo "PasswordAuthentication yes"  >> /etc/ssh/sshd_config
systemctl restart sshd

并且,/etc/pam.d/sshd也文件会被覆盖,我们进行还原:
先清空:

>/etc/pam.d/sshd;

再还原:

echo '#%PAM-1.0
auth       required     pam_sepermit.so
auth       include      password-auth
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    include      password-auth'>/etc/pam.d/sshd

至此,升级完成,先别关闭终端,直接新开一个终端,连接到服务器测试。

注意:如果新开终端连接的时,root密码报错,并且已经根据上面后续操作,那可能就是SElinux的问题,我们进行临时禁用:

setenforce 0

即可正常登录,然后修改/etc/selinux/config 文件:

sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

进行永久禁用SElinux即可。

如何删除名称以“-”开头的文件(连字符,即连字符或减号)?

如何删除文件名以破折号(连字符或减号)开头的文件-?我被放入远程OSX服务器中,并且我的目录中有以下文件:

tohru:~ $ ls -l
total 8
-rw-r--r--    1 me  staff  1352 Aug 18 14:33 --help
...

我该如何--help从CLI 删除?我有时会以不同的形式遇到此问题,这些文件易于创建,但很难消除。

我尝试使用反斜杠

rm \-\-help

我已经尝试过引号

rm "--help"

如何防止减号(连字符或连字符)被解释为选项?shellcommand-linermquotingoptions— 布莱恩·瑞贝因(Bryan Rehbein)
 source
https://googleads.g.doubleclick.net/pagead/ads?guci=2.2.0.0.2.2.0.0&client=ca-pub-0985488874840506&output=html&h=185&slotname=6265911322&adk=3390361236&adf=749455052&pi=t.ma~as.6265911322&w=739&fwrn=4&lmt=1607589096&rafmt=11&psa=1&format=739×185&url=https%3A%2F%2Fqastack.cn%2Funix%2F1519%2Fhow-do-i-delete-a-file-whose-name-begins-with-hyphen-a-k-a-dash-or-minus&flash=0&wgl=1&tt_state=W3siaXNzdWVyT3JpZ2luIjoiaHR0cHM6Ly9hZHNlcnZpY2UuZ29vZ2xlLmNvbSIsInN0YXRlIjo2fSx7Imlzc3Vlck9yaWdpbiI6Imh0dHBzOi8vYXR0ZXN0YXRpb24uYW5kcm9pZC5jb20iLCJzdGF0ZSI6MX1d&dt=1607589096153&bpp=10&bdt=751&idt=92&shv=r20201203&cbv=r20190131&ptt=9&saldr=aa&abxe=1&cookie=ID%3Dca4430823848d327-22b818ace4c4003d%3AT%3D1606204075%3ART%3D1606204075%3AS%3DALNI_Mbkru57lQXIIYRILmLVnNvhJD6RsA&prev_fmts=0x0&nras=1&correlator=2164803063742&frm=20&pv=1&ga_vid=675618944.1606204075&ga_sid=1607589096&ga_hid=1460359480&ga_fc=0&rplot=4&u_tz=480&u_his=1&u_java=0&u_h=864&u_w=1536&u_ah=824&u_aw=1536&u_cd=24&u_nplug=3&u_nmime=4&adx=291&ady=687&biw=1519&bih=754&scr_x=0&scr_y=0&eid=21066699%2C21066792%2C21066435%2C21067496%2C21067981&oid=3&pvsid=3260477188348453&pem=565&ref=https%3A%2F%2Fwww.google.com%2F&rx=0&eae=0&fc=1920&brdim=0%2C0%2C0%2C0%2C1536%2C0%2C1536%2C824%2C1536%2C754&vis=1&rsz=%7C%7CpEe%7C&abl=CS&pfx=0&fu=8328&bc=31&ifi=1&uci=a!1&fsb=1&xpc=yo2WU2lIgm&p=https%3A//qastack.cn&dtd=100


1
如果将此问题重命名为“如何删除名称以-开头的文件”,那就太好了。— 桑迪2010年


@桑迪同意; 我通常不喜欢更改问题的含义,但是在这种情况下,可接受的答案特定于此问题— Michael Mrozek


33
我觉得有点讽刺,rm --help实际上解释了如何删除以-。开头的文件名。不过,这是个好问题。— lesmana’9


1
@ jw013有时,有经验的用户可以轻松地获得帮助,但对于新手来说却不知所措。— iconoclast 2012年


1
我在使用BusyBox的rm的系统上遇到了这个问题。包括帮助在内的一切都很少,因此rm –help没有提供任何线索。— dslake

Answers:


497

使用“-”使rm停止解析命令行选项,如下所示:

rm -- --help

— Vegar Nilsen
 source


1
我知道这很简单……— Bryan Rehbein 2010年


2
rm命令的所有版本都支持该--参数吗?— 基思·汤普森


3
@KeithThompson-是大多数GNU工具的功能,因此它不适用于大多数非GNU(“非Linux”)Unix(例如BSD变体或某些嵌入式系统)— dtech


1
谢谢!那挽救了我的一天。当然,它可以在BSD(OSX)和其他命令上运行!— raskhadafi


8
@ dtech,getopt()和--GNU(SysIII,1980)之前是标准/ POSIX。除了一些例外情况(如echo),标准实用程序都可以理解--。如果其他命令未使用getopt()API来解析选项,则为YMMV。— 斯特凡Chazelas


213

或者你可以做

rm ./--help

— 埃德富
 source


7
没关系,但这似乎是最“正确”的。— James M.


2
这是我记得的那个。我总是必须使用“ rm—help”。— user603 2010年


25
即使对于不--特别对待的命令,此方法也始终有效。— jw013 2011年


而且它也可以以避免对其他类型的一些特殊对待(选项旁)特别命名的参数,如-文本或实用工具cdfoo=barawk— 斯特凡Chazelas


1
当文件以单破折号开头(而不是破折号)时,此方法有效rm -- <filename>— StockB


37

使用find它来做:

find . -name '--help' -delete

这是一个很好的方法,因为如果您有多个这样的文件可以删除,则可以通过简单地先运行find而无需-delete选择该选项来获得文件的预览列表,然后如果文件列表看起来不错就可以运行再次与-delete

实际上,避免rm使用find(尤其是先预览)是一个好习惯,它将帮助您避免犯错,rm *这不可避免地会折磨您一天。

但是请注意,该查找将在所有子目录中递归,因此您可能需要使用子目录深度约束来运行它,如下所示:

find . -maxdepth 1 -name '--help' -delete

这将查找限制为当前目录。— 阿库利奇
 source


可移植的是,您需要提供find要查看的文件/目录的列表。所以find . -name...-delete-maxdepth不是标准的选择无论是。— 斯特凡Chazelas


21

Vegar Nilsen和edfuh的答案非常好,并且是对此类问题的正确解决方案。

我确实想对此问题添加一个一般性的答复,以使您可以删除文件名困难的任何文件。首先使用ls -i或的某种形式获取其inode编号stat,然后通过使用inode编号在当前目录中搜索文件并rm在具有匹配的inode编号的文件上执行命令来删除文件

find . -inode <inode> -exec rm {}\;

由于inode编号在每个文件系统中都是唯一的,因此您可以使用此文件删除任何文件;unicode或使用转义字符。这是非常烦人的输入方式,所以我建议添加该行

TAB: menu-complete             # Tab: Cycles through the command
"\e[Z": menu-complete-backward # Shift-Tab: Cycles backwards

.inputrc如果您正在使用bash,则将其放入文件中。这使您可以循环浏览可能的完成列表(以获取更多信息)。— Baldur
 source


5
这种方式有两个问题:1)可以使用-delete时不要使用-exec rm;2)当您可以使用时,获取find -name '--help' -delete— 索引


我认为那行不通。它遍历当前目录及其所有子目录中的所有文件,并且毕竟仍会调用rm --help,但仍不会删除该文件。只要使用rm ./--help(或rm -i *— 基思·汤普森


1
@KeithThompson find在所有文件的命令行参数路径前添加前缀,因此它将运行rm ./--helprm ./sub/dirs/--help。要解决第二个问题,必须添加-maxdepth 1,但是所有这些实质上都是以一种更加绕行,复杂的方式应用@edfuh的解决方案,并且-delete比以往任何时候都更安全-exec rm— jw013 2011年


1
此命令的另一个问题是{}和之间必须有一个空格\;,否则它将不起作用。— Eugene S


索引节点可能是唯一的,但可能有多个具有相同索引节点的目录条目。这些称为硬链接。而且它们在每个文件系统中都是唯一的,因此您需要使用-xdev。那帮不了你ls -i --help— 斯特凡Chazelas


11

一个残酷的解决方案:

perl -e "unlink '--help' or die 'Could not unlink.';"

perl -e "rmdir '-d' or die 'Could not rmdir.';"

— 托马斯·霍拉迪
 source


8

Linux演练:创建一个带有破折号和空格的文件,然后将其删除。

小心!不要意外地运行一个rm -rf /或类似的级联删除命令。

如果您要删除的文件中包含星号或斜杠,请不要意外插入./**其他通配符,它​​们可能会级联删除您的操作系统。

创建一个名为“ –yo yo”的文件

eric@dev ~ $ touch -- "--yo yo"
eric@dev ~ $ ls
bin  --yo yo

首先,使用find查找它:

eric@dev ~ $ find . -name "*--yo yo*"
./--yo yo

确保find命令仅找到您要删除的一个文件:

然后通过-delete选项进行查找,以将其删除:

eric@dev ~ $ find . -name "*--yo yo*" -delete
eric@dev ~ $ ls
bin  

啊,它走了。— 埃里克·莱斯钦斯基
 source


2

午夜指挥官(mc)是最简单的,只需指向它并按F8;)— 马辛
 source


3
OP需要命令行(CLI)解决方案。— Francesco Turco 2012年


1
Midnight Commander是一种CLI解决方案。只需使用您的软件包管理器进行安装即可。(甚至可以在ssh上使用…)en.wikipedia.org/wiki/Midnight_Commander— daviewales


6
如何为apt-get install mc || yum install mc; mc不同的方向键和F8不是更容易rm ./--help— 2014年


3
@daviewales:Midnight Commander是从命令行启动的,并且在终端中运行,但是Midnight Commander中的所有键盘操作都不来自CLI(命令行界面),而是来自Midnight Commander的界面。-通常,命令行实用程序可以在脚本中运行(bash命令行历史记录除外)— Peter.O 2015年


1

这是我在找到此线程之前使用的解决方案。
用于vim“编辑”目录:

vim .

然后(在vim中)选择您的文件,点击del并确认删除。
完成后,退出vim:q— 阿蒂
 source


0

您是否尝试将目录名称添加为前缀:

$ rm ./-filename.txt dirname/-filename2.txt
$ mv ./-filename.txt filename.txt
$ cp teste ./-teste

通常,使用目录作为文件的前缀有助于避免解析器功能将“减号”字符错误地解释为命令选项。— 保罗·亨里克·莱利斯·戈纳尔维斯
 source


1
我相信先前的答案已经涵盖这一点。— Kusalananda


-3

如果要重命名文件(-.bar,mv将不起作用),请尝试以下操作:

cat >foo.bar <-.bar

使用命令之前:

rm -- -.bar

您应该能够在foo.bar中检查原始文件的内容

php 7.2 安装 mcrypt 扩展

升级 php 7.2 后,使用微信提供的加解密代码时,提示 call to undefined function mcrypt_module_open() ;大脑疯狂运转1秒钟后,得出结论:php 7.2的扩展有变动;查阅相关资料知晓,mcrypt 扩展从 php 7.1.0 开始废弃;自 php 7.2.0 起,会移到 pecl。还好,安装过程不复杂。

环境:centos 7

yum 安装依赖包:

yum install libmcrypt libmcrypt-devel mcrypt mhash

在 php 官网下载 mcrypt 包,php 扩展官网

  # wget  http://pecl.php.net/get/mcrypt-1.0.3.tgz

  # tar xf mcrypt-1.0.3.tgz

  # cd mcrypt-1.0.3

编译安装 mcrypt

  # /usr/local/php/bin/phpize

  # ./configure –with-php-config=/usr/local/php/bin/php-config  && make && make install

在php.ini加上扩展即可

extension=mcrypt.so

重启 php-fpm

/etc/init.d/php-fpm restart

Nginx location 匹配顺序整理

Nginx环境

a. 查看当前系统cat /etc/redhat-release

[root@nginx /]# cat /etc/redhat-release

CentOS release 6.7 (Final)

[root@nginx /]#

b. 查看系统内核uname –r

[root@nginx /]# uname -r

2.6.32-573.el6.x86_64

[root@nginx /]#

c. 安装的Nginx版本,/appliation/nginx/sbin/nginx -V

[root@nginx sbin]# ./nginx -V

nginx version: nginx/1.6.2

built by gcc 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)

TLS SNI support enabled

configure arguments: –user=nginx –group=nginx –prefix=/application/nginx1.6.2 –with-http_stub_status_module –with-http_ssl_module

[root@nginx sbin]#

location模块

Nginx location

location 指令的作用是根据用户请求的URI来执行不同的应用,URI就是根据用户请求到的网址URL进行匹配,匹配成功了进行相关的操作。

location语法

下面是官网的语法结构:

Syntax:    location [ = | ~ | ~* | ^~ ] uri { … }

location @name { … }

Default:   —

Context:   server, location

官网解释翻译和理解

下面会结合官网原文进行解释,以下英文部分均从官网摘抄:

http://nginx.org/en/docs/http/ngx_http_core_module.html#location

(翻译的不好勿喷)

Sets configuration depending on a request URI.

根据请求的URI进行配置

URI 变量是待匹配的请求字符串,

A location can either be defined by a prefix string, or by a regular expression.

Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching)

一个location可以用prefix string(前缀字符串)定义,也可以通过regular expression(正则表达式来定义)

通俗的说也就是:我们可以通过使用不同的前缀,表达不同的含义,对于不同的前缀可以分为两大类:普通location和正则location

符号:”~”表示uri包含正则,并且区分大小写

符号:“~*”表示uri包含正则,但不区分大小写

注意:如果你的uri用正则,则你的正则前面必须添加~或者~*,之前我在这里存在误区,以为可以不加~或者~*

To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

Nginx服务器会首先会检查多个location中是否有普通的uri匹配,如果有多个匹配,会先记住匹配度最高的那个。然后再检查正则匹配,这里切记正则匹配是有顺序的,从上到下依次匹配,一旦匹配成功,则结束检查,并就会使用这个location块处理此请求。如果正则匹配全部失败,就会使用刚才记录普通uri匹配度最高的那个location块处理此请求。

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

当普通匹配的最长前缀匹配有符号“^~”的时候,就不会在匹配正则

直接使用当前匹配的这个location块处理此请求

Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.

使用符号“=”修饰符可以定义一个精确匹配的URI和位置,如果找到了一个精确的匹配,则搜索终止,例如,如果一个”/”请求频繁发生,定义“location =/”将加快这些请求的处理,一旦精确匹配只有就结束,这样的location显然不能包含嵌套location

这里我们说一下location / {} 和location =/ {}的区别:

“location / {}”是普通的最大前缀匹配,任何的uri肯定是以“/”开头,所以location / {} 可以说是默认匹配,当其他都不匹配了,则匹配默认匹配

根据上述官网内容进行总结

a. ”=”用于普通uri前,要求精确匹配,如果匹配成功,则停止搜索并用当前location处理此请求

b. ”~” 表示uri包含正则,并且区分大小写

c. “~*”表示uri包含正则,但不区分大小写

d. ”^~”表示在普通uri前要求Nginx服务器找到普通uri匹配度最高的那个location后,立即处理此请求,并不再进行正则匹配

e. ”^~”和“=”都可以阻止继续匹配正则location两者的区别:“^~”依然遵守最大前缀原则,然后“=”是需要严格匹配

关于location网上的一些误解

location 的匹配顺序是“先匹配正则,再匹配普通”

这是一个错误的结论,从上面官网的文章中我们可以知道:

先匹配普通uri,然后记住匹配度最高的那个(官网原话:To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered.)然后匹配正则,如果正则匹配则结束查找,如果正则不匹配,则匹配之前普通匹配中匹配度最高的那个将执行该请求(官网原话:Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.)

所以:location 的匹配顺序是“先匹配正则,再匹配普通” 这句话肯定是错误的,况且这里并没有包含”^~”和“=”

location 的执行逻辑跟 location 的编辑顺序无关。

这也是一种错误的理解,我们根据上述内容可以知道:

如果是普通uri 匹配,这个时候是没有顺序的,但是正则匹配则是有顺序的,是从上到下依次匹配,一旦有匹配成功,则停止后面的匹配。

那么顺序到底是怎么匹配呢?

我画了一个location匹配的逻辑图便于理解匹配的顺序规则

通过实验来验证出结果

对www.conf配置如下:

[root@nginx extra]# cat www.conf

    server {

        listen       80;

        server_name  www.zhaofan.com;

        access_log      logs/access_www.log;

        root    html/www;

        location / {

            return 401;

        }

        location = / {

            return 402;

        }

        location  /documents/ {

            return 403;

        }

        location  ^~ /images/ {

            return 404;

        }

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

    }

[root@nginx extra]#

注意:

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

这个部分$前面不能有空格,否则会提示如下错误:

[root@nginx extra]# ../../sbin/nginx -s reload

nginx: [emerg] invalid location modifier “~*\.(gif|jpg|jpeg)” in /application/nginx1.6.2/conf/extra/www.conf:19

如果$后面没有空格,则会提示如下错误:

[root@nginx extra]# ../../sbin/nginx -s reload

nginx: [emerg] directive “location” has no opening “{” in /application/nginx1.6.2/conf/extra/www.conf:23

这些都是细节问题,一定要注意

实验一:登录nginx网站,我这里的直接打开:http://192.168.8.105/

可以看出这里是精确匹配

        location = / {

            return 402;

        }

实验二:打开http://192.168.8.105/aaa/

这里可以看出因为都不匹配,所以最后匹配了location / {}

        location / {

            return 401;

        }

实验三:打开http://192.168.8.105/1.gif

这里可以看出是匹配了正则

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

实验四:打开http://192.168.8.105/aaa/1.gif

这里依然是匹配正则

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

实验五:打开http://192.168.8.105/images/1.gif

        location / {

            return 401;

        }

        location = / {

            return 402;

        }

        location  /document/ {

            return 403;

        }

        location  ^~ /images/ {

            return 404;

        }

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

这里通过配置把实验三和实验四的对比就可以看出来因为普通匹配里有“^~”,并且匹配到了images,所以这个就是不进行正则匹配

        location  ^~ /images/ {

            return 404;

        }

实验六:“^~”遵守最大前缀原则

配置如下:

        location / {

            return 401;

        }

        location = / {

            return 402;

        }

        location  = /document/ {

            return 403;

        }

        location  ^~ /images/ {

            return 404;

        }

        location   /images/1/ {

            return 501;

        }

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

还是关注标红的地方,这个时候我们登陆:http://192.168.1.19/images/

结果如下:

从这里可以看出匹配了:

        location  ^~ /images/ {

            return 404;

        }

但是如果我们登陆:http://192.168.1.19/images/1/

结果如下;

这里匹配了:

        location   /images/1/ {

            return 501;

        }

从这里我们可以看出“^~”遵守最大匹配原则。

实验七:当最长匹配和精确匹配相同时

配置如下:

        location / {

            return 401;

        }

        location = / {

            return 402;

        }

        location  = /document/ {

            return 403;

        }

        location  ^~ /images/ {

            return 404;

        }

        location   /images/1/ {

            return 501;

        }

        location  =  /images/1/ {

            return 502;

        }

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

登陆:http://192.168.1.19/images/1/

结果如下:

但是如果这个时候登陆:http://192.168.1.19/images/1/aaa/

结果如下:

从这里我们可以看出当精确匹配和最长匹配相同时,匹配的是精确匹配。

不在过多的做实验,根据上面的逻辑图应该可以解决碰到的问题了所有的努力都值得期许,每一份梦想都应该灌溉!

原文:https://www.cnblogs.com/zhaof/p/5945576.html