我知道 Ubuntu 中有一个 GUISoftware & Updates可以启用更新渠道
- 更新
- 建议的
- 向后移植
- 安全
如该截图所示:
我正在寻找一种简单的方法来在终端内使用以下命令执行此操作
sudo apt-add-update enable updates
sudo apt-add-update enable proposed
sudo apt-add-update enable backports
sudo apt-add-update enable security
sudo apt-add-update disable updates
sudo apt-add-update disable proposed
sudo apt-add-update disable backports
sudo apt-add-update disable security
还有一件事
sudo apt-add-update enable default
sudo apt-add-update disable default
为了更好地理解,举几个例子
一个空的
sources.list
cat /etc/apt/sources.list
<empty>
sudo apt-add-update enable security
<empty>
一个已启用的存储库 (
main
)cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu wily main
sudo apt-add-update enable security
deb http://archive.ubuntu.com/ubuntu wily main deb http://archive.ubuntu.com/ubuntu wily-security main
一行或两行中启用两个或多个存储库
cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu wily main universe
或者
deb http://archive.ubuntu.com/ubuntu wily main deb http://archive.ubuntu.com/ubuntu wily universe
sudo apt-add-update enable security
deb http://archive.ubuntu.com/ubuntu wily main universe deb http://archive.ubuntu.com/ubuntu wily-security main universe
或者
deb http://archive.ubuntu.com/ubuntu wily main deb http://archive.ubuntu.com/ubuntu wily-security main deb http://archive.ubuntu.com/ubuntu wily universe deb http://archive.ubuntu.com/ubuntu wily-security universe
带有
deb-src
条目cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu wily main universe deb-src http://archive.ubuntu.com/ubuntu wily main universe
sudo apt-add-update enable security
deb http://archive.ubuntu.com/ubuntu wily main universe deb-src http://archive.ubuntu.com/ubuntu wily main universe deb http://archive.ubuntu.com/ubuntu wily-security main universe deb-src http://archive.ubuntu.com/ubuntu wily-security main universe
含有非活动
deb-src
条目cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu wily main universe # deb-src http://archive.ubuntu.com/ubuntu wily main universe
sudo apt-add-update enable security
deb http://archive.ubuntu.com/ubuntu wily main universe # deb-src http://archive.ubuntu.com/ubuntu wily main universe deb http://archive.ubuntu.com/ubuntu wily-security main universe
事情
default
cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu wily-security universe
sudo apt-add-update enable default
deb http://archive.ubuntu.com/ubuntu wily universe deb http://archive.ubuntu.com/ubuntu wily-security universe
只有一个条目和
disable
操作cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu wily-security universe
sudo apt-add-update disable security
<empty>
不同或相同的服务器用于不同或相同的存储库,尊重每个服务器
cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu wily universe deb http://us.archive.ubuntu.com/ubuntu wily main
sudo apt-add-update enable security
deb http://archive.ubuntu.com/ubuntu wily universe deb http://us.archive.ubuntu.com/ubuntu wily main deb http://archive.ubuntu.com/ubuntu wily-security universe deb http://us.archive.ubuntu.com/ubuntu wily-security main
不同的 Ubuntu 版本适用于不同的存储库,尊重每个版本
cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu wily main universe deb http://archive.ubuntu.com/ubuntu trusty main
sudo apt-add-update enable security
deb http://archive.ubuntu.com/ubuntu wily main universe deb http://archive.ubuntu.com/ubuntu trusty main deb http://archive.ubuntu.com/ubuntu wily-security main universe deb http://archive.ubuntu.com/ubuntu trusty-security main
PPA 或其他软件包源(非规范)
sources.list
?忽略!
不要更改协议,例如
https
,,,...http
tor
答案1
我分析了Ubuntu 软件中心写的python
。
之后,我编写了下面的代码,运行良好。aptsources
是 Ubuntu 软件中心用于管理/etc/apt/sources.list
和的 Python 模块/etc/apt/sources.list.d
。
#!/usr/bin/python
import aptsources.sourceslist
from subprocess import Popen, PIPE
import errno
import os
def _lsb_release():
"""Call lsb_release --idrc and return a mapping."""
result = {'Codename': 'sid', 'Distributor ID': 'Debian',
'Description': 'Debian GNU/Linux unstable (sid)',
'Release': 'unstable'}
try:
out = Popen(['lsb_release', '-idrc'], stdout=PIPE).communicate()[0]
# Convert to unicode string, needed for Python 3.1
out = out.decode("utf-8")
result.update(l.split(":\t") for l in out.split("\n") if ':\t' in l)
except OSError as exc:
if exc.errno != errno.ENOENT:
logging.warning('lsb_release failed, using defaults:' % exc)
return result
if __name__ == "__main__":
if len(os.sys.argv) != 3 or \
os.sys.argv[1] not in ['enable', 'disable'] or \
os.sys.argv[2] not in ['updates', 'security', 'proposed', 'backports', 'default']:
print "Usage: apt-add-update <enable|disable> <default|updates|security|proposed|backports>"
os.sys.exit(0)
release = _lsb_release()
codename = release['Codename']
sourcelist = aptsources.sourceslist.SourcesList()
template = None
main_uri = ""
main_comps = []
main_types = []
child_comps = []
child_types = []
for tmpl in sourcelist.matcher.templates:
if tmpl.name == codename and tmpl.distribution == "Ubuntu":
template = tmpl
break
updated = False
for source in sourcelist.list:
if source.invalid:
continue
for comp in source.comps:
if comp not in child_comps:
child_comps.append(comp)
if source.template and source.template.official and source.dist == codename and source.template.name == codename:
main_uri = source.uri
for comp in source.comps:
if comp not in main_comps:
main_comps.append(comp)
main_types.append(source.type)
else:
child_types.append(source.type)
if source.dist == codename + "-" + os.sys.argv[2]:
if os.sys.argv[1] == 'enable' and source.type in main_types:
source.set_enabled(True)
if os.sys.argv[1] == 'disable':
source.set_enabled(False)
updated = True
if source.dist == codename and os.sys.argv[2] == "default":
if os.sys.argv[1] == 'enable' and source.type in child_types:
source.set_enabled(True)
if os.sys.argv[1] == 'disable':
source.set_enabled(False)
updated = True
if not main_uri:
main_uri = "http://archive.ubuntu.com/ubuntu"
if os.sys.argv[2] == "default" and not main_comps:
main_comps = child_comps
if not main_comps:
main_comps = ['main', 'restricted', 'universe', 'multiverse']
if not updated and os.sys.argv[1] != 'disable':
if os.sys.argv[2] == "default":
uri = main_uri
if tmpl.base_uri:
uri = tmpl.base_uri
tmpl = template
line = tmpl.type + " " + uri + " " + tmpl.name + " " + " ".join(main_comps)
sourceentry = aptsources.sourceslist.SourceEntry(line)
sourcelist.list.append(sourceentry)
for tmpl in template.children:
if tmpl.name != codename + "-" + os.sys.argv[2] and \
not (os.sys.argv[2] == "default" and tmpl.name == codename):
continue
if os.sys.argv[2] == "default" and tmpl.type not in child_types:
continue
if os.sys.argv[2] != "default" and tmpl.type not in main_types:
continue
uri = main_uri
if tmpl.base_uri:
uri = tmpl.base_uri
if not uri:
continue
line = tmpl.type + " " + uri + " " + tmpl.name + " " + " ".join(main_comps)
sourceentry = aptsources.sourceslist.SourceEntry(line)
sourcelist.list.append(sourceentry)
sourcelist.save()
使用文件名保存此代码/usr/local/bin/apt-add-update
。然后按如下方式运行。
$ sudo apt-add-update <enable|disable> <default|updates|security|proposed|backports>
我更新它为多发行版支持,例如trusty
和wily
。
#!/usr/bin/python
import aptsources.sourceslist
import os
subdistnames = ['updates', 'security', 'proposed', 'backports']
def get_subdistname(distname):
rc = "default"
try:
rc = distname.split("-")[1]
except:
pass
return rc
def get_distname(distname):
rc = distname
try:
rc = distname.split("-")[0]
except:
pass
return rc
def duplicate_check(entries):
new_entries = []
for source in entries:
for newsource in new_entries:
if source.type == newsource.type and source.uri == newsource.uri and source.dist == newsource.dist:
for comp in newsource.comps:
if comp in source.comps:
source.comps.remove(comp)
if len(source.comps) > 0:
new_entries.append(source)
return new_entries
if __name__ == "__main__":
if len(os.sys.argv) != 3 or \
os.sys.argv[1] not in ['enable', 'disable'] or \
( os.sys.argv[2] not in subdistnames and os.sys.argv[2] != 'default' ):
print "Usage: apt-add-update <enable|disable> <default|updates|security|proposed|backports>"
os.sys.exit(0)
sourcelist = aptsources.sourceslist.SourcesList()
sourcelist.list = []
sourcelist.load('/etc/apt/sources.list')
main_entries = []
child_entries = []
other_entries = []
distro_names = []
for tmpl in sourcelist.matcher.templates:
if tmpl.name.find('-') > 0 or tmpl.distribution != "Ubuntu":
continue
distro_names.append(tmpl.name)
for source in sourcelist.list:
if source.invalid or source.disabled:
continue
subdistname = get_subdistname(source.dist)
if source.dist in distro_names:
main_entries.append(source)
elif subdistname in subdistnames:
child_entries.append(source)
else:
other_entries.append(source)
if os.sys.argv[2] in subdistnames:
modified = True
while modified:
modified = False
for source in child_entries:
if get_subdistname(source.dist) == os.sys.argv[2]:
child_entries.remove(source)
modified = True
continue
if os.sys.argv[1] == "enable":
for source in main_entries:
uri = source.uri
if os.sys.argv[2] == "security":
uri = "http://security.ubuntu.com/ubuntu"
comps = []
for i in source.comps:
if i in ['main', 'restricted', 'universe', 'multiverse']:
comps.append(i)
line = source.type + " " + uri + " " + source.dist + "-" + os.sys.argv[2] + " " + " ".join(comps)
sourceentry = aptsources.sourceslist.SourceEntry(line)
child_entries.append(sourceentry)
else:
main_entries = []
if os.sys.argv[1] == "enable":
for source in child_entries:
uri = source.uri
if get_subdistname(source.dist) == "security":
uri = "http://archive.ubuntu.com/ubuntu"
comps = []
for i in source.comps:
if i in ['main', 'restricted', 'universe', 'multiverse']:
comps.append(i)
line = source.type + " " + uri + " " + get_distname(source.dist) + " " + " ".join(comps)
sourceentry = aptsources.sourceslist.SourceEntry(line)
main_entries.append(sourceentry)
main_entries = duplicate_check(main_entries)
child_entries = duplicate_check(child_entries)
other_entries = duplicate_check(other_entries)
sourcelist.list = []
sourcelist.list.extend(main_entries)
sourcelist.list.extend(child_entries)
sourcelist.list.extend(other_entries)
sourcelist.save()
参考网址为https://github.com/dupingping/apt-add-update/tree/master
答案2
2015 年 11 月 27 日更新:
脚本的第二个版本仍然让我不满意,源代码过于臃肿,而且必须使用多种不同的工具。因此我尝试仅使用 AWK 重写脚本。
新脚本使用纯 AWK,并且更好地遵守了要求。本质上,它/etc/apt/sources.list
每次运行时都会重写。
运行脚本后,需要更新,因此sudo apt-get update
脚本成功退出后再运行。
该文件必须启用可执行权限chmod +x add-update.awk
,并保存在$PATH
变量中包含的任意目录中。特别建议将脚本保存到$HOME/bin
文件夹(也必须将其附加到变量中$PATH
)。
/etc/apt/sources.list
不需要备份原始文件,但强烈建议备份。要备份文件,请执行以下操作
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
用法:
sudo ./add-update.awk -v ACTION=[enable|disable|help] -v SOURCE=[updates|backports|security|proposed]
演示:
sergrep:$ cat /etc/apt/sources.list
deb http://it.archive.ubuntu.com/ubuntu wily main universe
deb http://us.archive.ubuntu.com/ubuntu wily-backports main
deb-src http://it.archive.ubuntu.com/ubuntu wily main universe
deb-src http://us.archive.ubuntu.com/ubuntu wily-backports main
# removed
sergrep:$ sudo ./add-update.awk -v ACTION="enable" -v SOURCE="security"
[sudo] password for xieerqi:
/etc/apt/sources.list
<<< Script finished processing
sergrep:$ cat /etc/apt/sources.list
deb http://it.archive.ubuntu.com/ubuntu wily main universe
deb http://it.archive.ubuntu.com/ubuntu wily-security main universe
deb http://us.archive.ubuntu.com/ubuntu wily-backports main
deb http://us.archive.ubuntu.com/ubuntu wily-security main
deb-src http://it.archive.ubuntu.com/ubuntu wily main universe
deb-src http://it.archive.ubuntu.com/ubuntu wily-security main universe
deb-src http://us.archive.ubuntu.com/ubuntu wily-backports main
deb-src http://us.archive.ubuntu.com/ubuntu wily-security main
源代码
#!/usr/bin/awk -f
#
###########################################################
# Author: Serg Kolo
# Date: Nov 27,2015
# Purpose: A script that enables/disables 4 ubuntu sources
# (namely updates, backports, proposed, and security )
# much in a way like software-properties-gtk does
# Written for: http://paste.ubuntu.com/13434218/
###########################################################
#
# Permission to use, copy, modify, and distribute this software is hereby granted
# without fee, provided that the copyright notice above and this permission statement
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
function printUsage() {
print "Usage: sudo ./add-update.awk -v ACTION=[enable|disable|help] -v SOURCE=[updates|backports|security|proposed]";
exit
}
function checkSourceEnabled()
{
if ( $3 ~ SOURCE) {
print SOURCE" is enabled; exiting"
VAL = 1
}
else {
VAL = 0
}
return VAL
}
function disableSource()
{
if ( $0 ~ SOURCE ) $0="# removed";
j++;
newLines[j]=$0;
}
function listStuff () {
for(k=4; k<=NF; k++) if ( $k~/#/ ) {break} else {
COMPONENTS=COMPONENTS" "$k
};
gsub(/\-.*/,"",$3);
STRING=$1" "$2" "$3APPEND" "COMPONENTS;
COMPONENTS=""
return STRING;
}
function replaceFile()
{
command="mv /tmp/sources.list "ARGV[1]
system(command);
}
############
# MAIN
#############
BEGIN {
# argument checking sequence
# must remain written in if-else
# structure rather than case,
# to consider users who may not be able
# to install gawk due to broken sources.list
# which is what this script should be aimed at
# actions checked first so that
# help message can be printed
if ( ACTION == "enable" ||
ACTION == "disable" ||
ACTION == "default" ) {
print "<<< ACTION ARG OK"
}
else if (ACTION == "help" ){
printUsage()
exit
}
if ( SOURCE == "update" ||
SOURCE == "security" ||
SOURCE == "backports" ||
SOURCE == "proposed" ) {
print "<<< SOURCE ARG OK"
}
else if ( ACTION != "default" || ACTION != "help" ) {
print "<<< E: SOURCE ARG INCORRECT";
printUsage();
exit 1 }
# static filename to operate on
ARGV[ARGC++]="/etc/apt/sources.list";
if (ACTION == "enable" ) {
APPEND="-"SOURCE;
} else{
APPEND="";
}
} # END OF BEGIN
$0~/^deb*/ && $0!~/partner/ && $0!~/extra/ {
if ( ACTION == "enable" ) {
j++;
ARRAY[j]=$0
ENABLED=checkSourceEnabled();
if ( ENABLED ) {
exit 1
}
else {
j++;
ARRAY[j]=listStuff();
}
}
else if ( ACTION == "disable" ){
disableSource() ;
}
else if ( ACTION == "default" && SOURCE == "default" ) {
j++;
defaultsArray[j]=$0;
j++;
defaultsArray[j]=listStuff();
}
}
END {
print "<<< Script finished processing" ;
if ( ACTION =="enable" && ENABLED == 0 ){
for(i=1;i<=j;i++)
print ARRAY[i] | "sort -u > /tmp/sources.list ";
replaceFile();
}
else if ( ACTION == "disable" ) {
for ( i=1;i<=j;i++ ) print newLines[i] | "sort -u > /tmp/sources.list"
replaceFile();
}
else if (ACTION == "default" ){
for ( i=1;i<=j;i++ ) print defaultsArray[i] | "sort -i -u > /tmp/sources.list"
replaceFile();
}
}
# END OF MAIN
--
之前的版本
答案3
用法:
## testing
apt-add-update enable|disable default|security|updates|proposed|backports [file]
## real
sudo apt-add-update enable|disable default|security|updates|proposed|backports
以下为要点:
我解析了该文件,因为我自己正在寻找一些其他选项。
检查是否有镜像,无论是官方的(包括旧版本、端口)还是从
python-apt
包加载的社区提供的其他镜像(它包含一个包含所有镜像的文件)。/usr/share/python-apt/templates/Ubuntu.mirrors
始终将官方 URI 保留在文件中。因此,即使禁用所有 URI,它也会保留注释行以进行持久性设置。它使用字母排序类型、url、dist、comp 将行解析为最少。
如果获取输入文件作为第三个参数或者没有写入权限,则打印到标准输出
/etc/apt/sources.list
- 不支持
[ options ]
喜欢[ arch=amd64 ]
。 - 我强制
disable default
用户指定要禁用的内容。 - 我不喜欢最后一个选项(9),因为我故意混合了 repo。因此它们应该被视为第三方存储库。
下载:带有完整的测试集。
https://github.com/sneetsher/au_700860_apt_channels
脚本:
#!/usr/bin/python3
import sys,os
import re
## official repo's
#http://ports.ubuntu.com/ubuntu-ports/
#http://old-releases.ubuntu.com/ubuntu/
#http://security.ubuntu.com/ubuntu/
#http://archive.ubuntu.com/ubuntu/
repo_official_uri_re = re.compile(r"\A(http|ftp)://(([a-zA-Z]*.)?archive|security|old-releases|ports).ubuntu.com/ubuntu(-ports)?[/]?\Z")
## load other mirrors
mirrors=[]
mir_re = re.compile(r"\A(http|ftp)://")
with open("/usr/share/python-apt/templates/Ubuntu.mirrors","r") as f:
for l in f:
if mir_re.match(l):
mirrors.append(l.strip())
f.close()
#print(mirrors)
## system release
with open("/etc/lsb-release","r") as f:
for l in f:
k,v=l.split("=")
if k=="DISTRIB_CODENAME":
release = v.strip()
break
#print(release)
f.close()
## load sources.list
##TODO: missing support deb line options like [ arch=whatever ]
emp_re = re.compile(r"\A\s*\Z")
repo_re = re.compile(r"\A#* *deb(-src)? *(http://|ftp://|file://|cdrom:)")
com_re = re.compile(r"\A#")
repo_details_re = re.compile(r"\A(?P<active>#*) *(?P<type>deb(-src)?) *(?P<uri>(http://|ftp://|file://|cdrom:\[[a-zA-Z0-9 \-_().]*\])?\S*) (?P<dist>[a-zA-Z\-_]*) (?P<comp>[a-zA-Z ]*\Z)")
##example
sources={
"http://archive.ubuntu.com/ubuntu/":{
"active":True,
"deb":{
"wily":["universe","multiverse","restricted","main"],
"wily-security":["main","restricted","universe","multiverse"]
},
"deb-src":{
"wily":["universe","multiverse","restricted","main"]
},
"mirror":True
}
}
sources={}
uri=""
##for testing
if len(sys.argv)>=4 and os.path.isfile(sys.argv[3]):
ifile = sys.argv[3]
else:
ifile = "/etc/apt/sources.list"
with open(ifile, "r") as f:
for l in f:
l=l.strip()
r = emp_re.match(l)
if r:
continue
else:
#print("raw:",l)
r = repo_re.match(l)
if r:
#print("repository:",l)
r = repo_details_re.match(l)
#print(r.groupdict())
uri=r.group("uri")
if uri[-1]!="/":
uri += "/"
if (uri not in sources):
sources[uri] = {"active":False,"deb":{},"deb-src":{},"mirror":False}
m = repo_official_uri_re.match(uri)
if m or uri in mirrors:
sources[uri]["mirror"] = True
if r.group("active")=="":
sources[uri]["active"]=True
sources[uri][r.group("type")][r.group("dist")]=r.group("comp").split()
else:
if r.group("active")=="" and sources[uri]["active"]==False:
sources[uri]["active"]=True
sources[uri]["deb"]={}
sources[uri]["deb-src"]={}
sources[uri][r.group("type")][r.group("dist")]=r.group("comp").split()
if (r.group("active")=="")==sources[uri]["active"]:
if r.group("dist") not in sources[uri][r.group("type")]:
sources[uri][r.group("type")][r.group("dist")]=r.group("comp").split()
else:
for c in r.group("comp").split():
if c not in sources[uri][r.group("type")][r.group("dist")]:
sources[uri][r.group("type")][r.group("dist")].append(c)
else:
r = com_re.match(l)
if r:
#print("comment",l)
continue
else:
print("unknown",l)
#print(sources)
f.close()
## process argumments
#fallback for default component to be copied from
comp=[release+"-security",release+"-update",release+"-proposed"]
found_other_comp=False
if sys.argv[2]=="default" and sys.argv[1]=="enable":
for u in sorted(sources.keys()):
if sources[u]["mirror"]:
if sources[u]["active"]:
for t in ["deb","deb-src"]:
if release not in sources[u][t]:
for d in range(len(comp)):
if comp[d] in sources[u][t]:
other_comp_found=True
for i in range(d):
sources[u][t][comp[i]]=sources[u][t][comp[d]]
sources[u][t][release]=sources[u][t][comp[d]]
###don't activate any thing if commented like an empty file.
#if not found_other_comp and t=="deb":
# sources[u][t][release]=["main"]
#else:
# sources[u]["active"]=True
# sources[u]["deb"]={release:["main"]}
# sources[u]["deb-src"]={}
## carry on enable security
sys.argv[2] = "security"
if sys.argv[2]=="security" or sys.argv[2]=="updates" or sys.argv[2]=="proposed" or sys.argv[2]=="backports":
for u in sorted(sources.keys()):
if sources[u]["mirror"] and sources[u]["active"]:
if sys.argv[1]=="disable":
if len(sources[u]["deb"])+len(sources[u]["deb-src"])>(release+"-"+sys.argv[2] in sources[u]["deb"])+(release+"-"+sys.argv[2] in sources[u]["deb-src"]):
if release+"-"+sys.argv[2] in sources[u]["deb"]:
del sources[u]["deb"][release+"-"+sys.argv[2]]
if release+"-"+sys.argv[2] in sources[u]["deb-src"]:
del sources[u]["deb-src"][release+"-"+sys.argv[2]]
else:
sources[u]["active"] = False
elif sys.argv[1]=="enable":
for t in ["deb","deb-src"]:
if release in sources[u][t]:
if release+"-"+sys.argv[2] not in sources[u][t]:
sources[u][t][release+"-"+sys.argv[2]]=sources[u][t][release]
else:
for c in sources[u][t][release]:
if c not in sources[u][t][release+"-"+sys.argv[2]]:
sources[u][t][release+"-"+sys.argv[2]].append(c)
## generate the new list
data_out=""
for u in sorted(sources.keys()):
#print(u)
for t in ["deb","deb-src"]:
for d in sorted(sources[u][t].keys()):
data_out += (not sources[u]["active"])*"#"+" ".join([t,u,d,""])+" ".join(sorted(sources[u][t][d]))+"\n"
if len(sys.argv)>=4 or not os.access("/etc/apt/sources.list", os.W_OK):
print(data_out)
else:
with open("/etc/apt/sources.list","w") as f:
f.write(data_out)
f.close()
sys.exit(0)
答案4
这正是所要求的;
如果有必要,我会不时更新它;
最新版本可以在这里找到GitHub 存储库;
要从 GitHub 存储库安装:
- 安装
git
:sudo apt-get install git
- 克隆存储库:
git clone https://github.com/kos0/addRemoveDistribution.git
概要:
enableDisableDistribution.pl <enable|disable> <default|security|updates|proposed|backports>
#!/usr/bin/perl
sub printUsage {
print("Usage: enableDisableDistribution.pl \e[4maction\e[0m \e[4mdistribution\e[0m\n\n");
print("\e[4maction\e[0m must be \e[1menable\e[0m or \e[1mdisable\e[0m\n");
print("\e[4mdistribution\e[0m must be \e[1mdefault\e[0m, \e[1msecurity\e[0m, \e[1mupdates\e[0m, \e[1mproposed\e[0m or \e[1mbackports\e[0m");
exit(0);
}
sub parse {
open(my $in, "/etc/apt/sources.list") || die("Couldn't open '/etc/apt/sources.list': $!");
while(<$in>) {
my $matchDistribution;
chomp;
if(/^deb(-src)? +(.*?).ubuntu.com\/ubuntu\/? +(.*?) +(.*?) *(#.*)?$/) {
my $debSrc = $1 eq "-src";
my $URI = $2;
my @split = split("-", $3);
my @components = sort(split(" ", $4));
if(($distribution eq "default" && defined($split[1])) || ($distribution ne "default" && $split[1] ne $distribution)) {
push(@add, "$debSrc,$URI,$split[0],@components");
}
else {
$matchDistribution = 1;
}
}
(! $matchDistribution && push(@notMatchDistribution, $_)) || push(@matchDistribution, $_);
}
close($in);
}
sub update {
while(1) {
print("Would you like to update the cache? Y-y/N-n: \n");
my $update = <STDIN>;
if($update =~ /^y$/i) {
my $ret = system("apt-get update");
exit($ret);
}
elsif($update =~ /^n$/i) {
exit(0);
}
else {
print("Please enter Y-y or N-n.\n");
}
}
}
sub rewrite {
if($action eq "enable") {
if(@matchDistribution == 0) {
open(my $out, ">", "/etc/apt/sources.list") || die("Couldn't open '/etc/apt/sources.list': $!");
foreach(@notMatchDistribution) {
print $out ($_ . "\n");
}
foreach(@add) {
my @x = split(",");
my @y = split(" ", $x[3]);
my $line = sprintf("deb%s $x[1].ubuntu.com/ubuntu $x[2]%s @y", $x[0] && sprintf("-src"), $distribution ne "default" && sprintf("-$distribution"));
if(! grep(/^$line$/, @added)) {
print $out ($line . " #Added by enableDisableDistribution\n");
push(@added, $line);
}
}
close($out);
printf("Added %s %s.\n", scalar(@added), @added == 1 ? sprintf("entry") : sprintf("entries"));
update;
}
else {
print("$distribution is enabled already. Aborting.\n");
exit(1);
}
}
else {
if(@matchDistribution > 0) {
open(my $out, ">", "/etc/apt/sources.list") || die("Couldn't open '/etc/apt/sources.list': $!");
foreach my $line (@notMatchDistribution) {
print $out ($line . "\n");
}
close($out);
printf("Removed %s %s.\n", scalar(@matchDistribution), @matchDistribution == 1 ? sprintf("entry") : sprintf("entries"));
update;
}
else {
print("$distribution is disabled already. Aborting.\n");
exit(1);
}
}
}
if($> != 0) {
print("You must be root to run enableDisableDistribution.\n");
exit(1);
}
if(@ARGV == 2 && $ARGV[0] =~ /^(enable|disable)$/ && $ARGV[1] =~ /^(default|security|updates|proposed|backports)$/) {
$action = $ARGV[0];
$distribution = $ARGV[1];
}
else {
printUsage;
}
parse;
rewrite;
exit(0);