├── LICENSE ├── README.md └── codeserver.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 coderpiaobozhe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vscode-server-download-script 2 | 3 | 4 | # 零、使用方法 5 | 6 | 7 | 1. 本脚本是在本地设备上执行的。使用本脚本前建议先把本地设备上的ssh公钥上传到服务器上,让本地设备能免密登录服务器(不传也可以,就是麻烦); 8 | 2. 本脚本假设本地设备是能联网的,而服务器则不可以(或者无法在联网状态下正常更新)。**如果你的服务器能联网,那你不需要本脚本**;如果你的服务器不能联网,你什么都不需要改,直接运行本脚本就可以了。**此外本脚本还假设服务器系统是某个Linux发行版**; 9 | 3. 如果本地设备的操作系统是某个Linux发行版(或者其他能直接运行shell脚本的系统),那本脚本是可以直接运行的;如果是windows系统(或者其他不能直接运行shell脚本的系统),那你需要下载git和wget,在git提供的终端里面运行本脚本,亲测有效; 10 | 4. 给这个脚本赋予执行权限并执行它:chmod +x codeserver.sh && ./codeserver.sh,接下来根据提示操作即可; 11 | 5. 使用前一定要把远程服务器上.vscode-server/bin目录下的${commit id}文件夹删除掉,也就是说每次更新完vscode后,先不要打开vscode(不然的话vscode会自动在远程服务器上.vscode-server/bin目录下创建${commit id}文件夹,而且会给该文件夹上锁,那样会导致更新失败),先运行完这个脚本再打开vscode; 12 | 6. 这个脚本可以直接删掉后缀名,然后放到相应的路径里面当成命令使用:Linux下可以放在/usr/local/bin一类的目录下,而windows下需要把这个命令放在git的命令目录下(C:/Program Files/Git/cmd和C:/Program Files/Git/mingw64/bin这两个目录中选一个,推荐后者,建议把wget命令也放在里面); 13 | 14 | 15 | # 一、vscode-server是如何工作的 16 | 17 | 18 | 1. 使用vscode远程连接到服务器上需要在服务器上下载vscode-server; 19 | 2. .vscode-server的内部目录结构如下: 20 | ```bash 21 | |-.vscode-server 22 | |-bin 23 | |-${commit id1} 24 | |-${commit id2} 25 | |-... 26 | |-data(不一定有) 27 | |-extensions(不一定有) 28 | |-... 29 | ``` 30 | 3. 每个版本的vscode都对应一个commit id,当远程连接到服务器时,本地设备上vscode的commit id会被传上去; 31 | 4. 如果在.vscode-server/bin/目录下有与传上去的commit id同名的文件夹,服务器会直接完成远程链接的相关工作; 32 | 5. 如果不符合第4步中提到的情况,在完成远程连接的相关工作前,服务器就会试图从vscode官方提供的网站下载对应的文件并把它们放到相应的目录下; 33 | 6. vscode每次更新版本时就会换commit id,所以每次更新后服务器都会执行第5步中提到的操作; 34 | 35 | 36 | # 二、为什么vscode有时不能完成上述工作以至于需要我们自行完成相关操作 37 | 38 | 39 | 自2023年的某月始,出于某些未知原因,vscode官方提供的网站 https://update.code.visualstudio.com 无法稳定访问。因此,我们需要把该网址换成国内的cdn https://vscode.cdn.azure.cn [该问题已解决] 40 | 41 | 2023年11月开始,由于vscode官方换了新的更新网站,https://vscode.cdn.azure.cn 已经被弃用了,新的网址是 https://vscode.download.prss.microsoft.com 。该网站是中国内外统一使用的,Visaul Studio Code官方特地在中国部署了几个服务器节点。所以如果你的服务器能联网,那么现在你就不需要本脚本的帮助了。 42 | 43 | # 三、常见问题 44 | 45 | 46 | 问:本脚本能彻底解决vscode ssh连接问题吗? 47 | 48 | 答:暂时不能。首先,config文件的配置形式是多种多样的:ssh端口可以换,proxyjump也可以设置。我暂时还没想好如何处理config文件中的内容。 49 | 50 | 问:为什么不默认用bash执行? 51 | 52 | 答:因为我本人用的zsh,为了提高脚本兼容性,所以选择最基础的sh。 53 | 54 | 问:能不能出一个windows系统下直接运行的batch脚本? 55 | 56 | 答:暂无这个计划,毕竟windows上也能靠git的终端运行这个脚本。当然了,最主要的问题是我不会batch语法。 57 | 58 | 问:为什么不让用户手动输入lk的值来确定选择哪种解决方略? 59 | 60 | 答:对于大部分人来说,服务器的联网状态是比较稳定的。能联网的服务器会长期保持联网的状态,不能联网的服务器也会长期保持不能联网的状态。每次让用户输入lk的值只会给用户增加麻烦。 61 | 62 | 问:为什么不在每次执行命令的时候在服务器上覆盖掉同名的文件夹? 63 | 64 | 答:因为谁都不能保证每次下载下来的包是完好无损的。用损坏掉的文件覆盖掉正常文件的损失会比较严重,而手动删掉不正常的文件顶多就是麻烦一些。 65 | 66 | 问:为什么下载的文件一定是vscode-server-linux-x64.tar.gz? 67 | 68 | 答:选择下载哪个vscode-server文件时需要考虑三个因素:本地设备vscode的版本、远程服务器的系统以及架构。在我的使用场景下,远程服务器都在使用Linux发行版,使用的架构基本都是x86_64,为了简便我就把这种情况设置为默认选项。我相信这也是绝大多数人面临的情况。后面我会对此进行更新:让脚本根据服务器的情况自动选择合适的文件下载。 69 | -------------------------------------------------------------------------------- /codeserver.sh: -------------------------------------------------------------------------------- 1 | # !/bin/sh 2 | # 标志全部服务器是否都可以联网,为1表示可以,为0表示不可以。如果不能的话在本地下载文件传到服务器上 3 | lk=0 4 | 5 | index=0 6 | hosts="" 7 | usernames="" 8 | ipaddresses="" 9 | 10 | # 获取本地vscode信息 11 | 12 | cmt=$(code --version | awk 'NR==2 {print $0}') 13 | if [ $lk -eq 0 ];then 14 | if ls $HOME/vscode-server-linux-$plat.tar.gz* 1> /dev/null 2>&1;then 15 | rm -rf $HOME/vscode-server-linux-x64.tar.gz* 16 | fi 17 | wget -P $HOME https://vscode.download.prss.microsoft.com/dbazure/download/stable/$cmt/vscode-server-linux-x64.tar.gz 18 | fi 19 | 20 | # 读取`~/.ssh/config`文件中的内容 21 | 22 | while IFS= read -r line; do 23 | case "$line" in 24 | Host[\ \t]*[0-9a-zA-Z_\-\.]*) 25 | # echo "Host->$line" 26 | if [ $index -gt 0 ];then 27 | echo "$index: $current_host - $current_user@$current_ip" 28 | fi 29 | current_host=$(echo "$line" | awk '{print $2}') 30 | hosts="$hosts $current_host" 31 | index=$((index+1)) 32 | ;; 33 | [\ \t]*HostName[\ \t]*[0-9a-zA-Z_\-\.]*) 34 | # echo "HostName->$line" 35 | current_ip=$(echo "$line" | awk '{print $2}') 36 | ipaddresses="$ipaddresses $current_ip" 37 | ;; 38 | [\ \t]*User[\ \t]*[0-9a-zA-Z_\-\.]*) 39 | # echo "User->$line" 40 | current_user=$(echo "$line" | awk '{print $2}') 41 | usernames="$usernames $current_user" 42 | ;; 43 | esac 44 | done < $HOME/.ssh/config 45 | echo "$index: $current_host - $current_user@$current_ip" 46 | 47 | # 让用户选择要在哪些服务器上执行操作 48 | 49 | read -p "请输入要执行操作的服务器序号,多个服务器请用逗号分隔,如果需要添加几台服务器就输入几个0,范围选择请用短横线(如0-5): " selected 50 | raw_selected_hosts=$(echo $selected | tr ',' ' ') 51 | selected_hosts="" 52 | for i in $raw_selected_hosts; do 53 | case "$i" in 54 | [0-9]*\-[0-9]*) 55 | tmp=$(echo "$i" | tr '-' ' ') 56 | lrange=$(echo "$tmp" | awk '{print $1}') 57 | rrange=$(echo "$tmp" | awk '{print $2}') 58 | j="$lrange" 59 | while [ "$j" -le "$rrange" ]; do 60 | selected_hosts="$selected_hosts $j" 61 | j=$((j+1)) 62 | done 63 | ;; 64 | [0-9]*) 65 | selected_hosts="$selected_hosts $i" 66 | ;; 67 | esac 68 | done 69 | 70 | for i in $selected_hosts; do 71 | if [ $i -eq 0 ];then 72 | read -p "请输入新服务器的Host名称: " host 73 | read -p "请输入新服务器的IP地址: " ip 74 | read -p "请输入新服务器的用户名: " user 75 | echo "Host $host" >> $HOME/.ssh/config 76 | echo " HostName $ip" >> $HOME/.ssh/config 77 | echo " User $user" >> $HOME/.ssh/config 78 | echo "" >> $HOME/.ssh/config 79 | else 80 | set -- $hosts 81 | host=$(eval echo \$$i) 82 | set -- $usernames 83 | user=$(eval echo \$$i) 84 | set -- $ipaddresses 85 | ip=$(eval echo \$$i) 86 | # echo "$host - $user@$ip" 87 | fi 88 | if [ $lk -eq 0 ]; then 89 | scp "$HOME/vscode-server-linux-x64.tar.gz" "$user@$ip:~" 90 | fi 91 | ssh -T "$user@$ip" <