最近闲着无聊,了解了一下bash命令,写了一个自动修改shadowsocks密码的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#!/bin/bash #================================================================ # Script for Shadowsocks Single User Password Renewing on Ubuntu/Debian # @author minirplus # Usage: ./ss-password-renew.sh # More info: https://blog.minirplus.com/5800/ #================================================================ # get old password old_password=$(grep password /etc/shadowsocks.json) password_index=$(expr index "$old_password" :) old_password=${old_password:password_index} old_password=${old_password%%,*} old_password=${old_password// /} old_password=${old_password:1:$((${#old_password}-2))} echo "your old password is $old_password" # generate new password new_password=$RANDOM echo "your new password is $new_password" # replace old password to new password echo "replace new password $new_password to the shadowsocks config file..." sed -i 's/'"$old_password"'/'"$new_password"'/g' /etc/shadowsocks.json # restart shadowsocks service echo "Restarting shadowsocks service..." /usr/local/bin/ssserver -c /etc/shadowsocks.json -d restart # All Done! echo "All Done!" echo "You can now use new password $new_password to login shadowsocks service now!" |
运行结果如下
1 2 3 4 5 6 7 8 9 10 |
root@vps:~# /usr/local/sbin/change-shadowsocks-password your old password is 28882 your new password is 20713 replace new password 20713 to the shadowsocks config file... Restarting shadowsocks service... INFO: loading config from /etc/shadowsocks.json 2016-02-15 17:17:33 INFO loading libcrypto from libcrypto.so.1.0.0 stopped started All Done! You will now can use new password 20713 to login shadowsocks service |
shadowsocks配置文件如下
1 2 3 4 5 6 7 8 9 10 |
{ "server":"0.0.0.0", "server_port":8381, "local_address": "127.0.0.1", "local_port":1080, "password":"20713", "timeout":300, "method":"aes-256-cfb", "fast_open": false } |
经验
学习Bash命令最开始碰到的问题是变量如何赋值和调用,之前在安装Let’s Encrypt的时候有一个renew脚本,看了下它的变量写法,了解到有两种不同的格式,一种是不带$的,一种是带$的,前一种用于给变量赋值,后一种用于调用变量的值。这两者的区别在刚开始写脚本的时候非常的头晕,特别是修改变量的值的时候,在bash中是相当于重新赋值,是不带$的,还有在进行Arithmetic Expansion的时候也是不需要带$的,这个非常容易出错。
例如下面这个截取字符串命令中两个变量都是不带$的
1 |
${old_password:password_index} |
之后碰到的问题是如何对已经赋值的变量进行算数操作,如果直接用操作符,那么变量就会变成字符串
例如字符串进行去头去尾,要对获取的字符串长度-2,如果直接stringlength-2,那么就会变成字符串,这个时候要用 $((string-2)) 将字符串包含起来,告诉系统这是一个算数操作
下面这个脚本就是用于对字符串去头去尾操作
1 |
${old_password:1:$((${#old_password}-2))} |
其中 ${#old_password} 用于获取变量old_password长度, $((${#old_password}-2)) 进行去头去尾共计-2个字符长度
之后是如何替换config文件中的内容,网上有用grep+sed,在shell中可以运行,但是到bash里就会出错,sed无法获取grep输出的path。遂改为简单的直接用sed进行替换。这里又碰到一个问题,就是如何在sed里用变量,有说直接用双引号就可以,但是在调试的时候一直出错,不知道问题在哪里,所以改为单引号加双引号,后来发现问题不在这里,所以其实不必这么麻烦。
在用 ${#old_password} 测量字符串长度的时候一直发现结果一直要比屏幕显示的字符串多,才发现原来这才是用sed命令一直出错的原因,估计是config文件是windows编码的,所以可能换行算一个字符,最后把逗号后的字符串清除,就不再出错了。
问题
1 |
-bash: /usr/local/sbin/change-shadowsocks-password: /bin/bash^M: bad interpreter: No such file or directory |
出现以上错误是由于代码是在Windows环境中编辑和上传,而Windows中换行的格式和Unix环境不同导致出现该问题。
解决方法是在Notepad++中的Edit -> EOL Conversion修改为Unix格式后重新上传。
查看换行格式可以点击Notepad++中的Show All Characters
There are no comments yet