以简单的终端方式添加和删除更新通道

我知道Ubuntu 软件和更新中有一个GUI来启用更新通道

  • 更新
  • 建议
  • 反向移植
  • 安全

如截图所示:

在此处输入图像描述

我正在寻找一种简单的方法,使用诸如此类的命令在终端内执行此操作

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 

一些例子可以更好地理解

  1. 一个空的sources.list

    • cat /etc/apt/sources.list

        
    • sudo apt-add-update enable security

        
  2. 一个启用的存储库( 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 
  3. 一行或两行中有两个或多个已启用的存储库

    • 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 
  4. 使用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 
  5. 使用非活动的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 
  6. 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 
  7. 只有一个条目和disable操作

    • cat /etc/apt/sources.list

       deb http://archive.ubuntu.com/ubuntu wily-security universe 
    • sudo apt-add-update disable security

        
  8. 对于不同或相同的存储库,不同或相同的服务器,尊重每个服务器

    • 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 
  9. 针对不同存储库的不同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 
  10. sources.list中的PPA或其他包源(非Canonical)?

    忽视!

  11. 不要更改协议,例如httpshttptor ,……

这完全符合要求;

如有必要,我会不时更新;

最新版本可以在这个GitHub存储库中找到;

要从GitHub存储库安装:

  • 安装gitsudo apt-get install git
  • 克隆存储库: git clone https://github.com/kos0/addRemoveDistribution.git

概要:

 enableDisableDistribution.pl   

S1

S2

S3

 #!/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? Yy/Nn: \n"); my $update = ; if($update =~ /^y$/i) { my $ret = system("apt-get update"); exit($ret); } elsif($update =~ /^n$/i) { exit(0); } else { print("Please enter Yy or Nn.\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); 

我分析了用python编写的Ubuntu软件中心的来源。

之后,我写了下面的代码运行良好。 aptsources是Ubuntu软件中心用来管理/etc/apt/sources.list/etc/apt/sources.list.d的python模块。

 #!/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  " 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   

更新了它的多发行版支持 ,例如trustywily

 #!/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  " 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() 

参考url是https://github.com/dupingping/apt-add-update/tree/master

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] 

源于github

演示:

 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 

-

之前的版本

github上的版本#1(带有AWK和SED的bash脚本)

github上的版本#2(也是bash脚本)

用法:

 ## 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保留在文件中。 因此,即使所有已禁用,它也会为持久性设置保留注释行。 它使用字母排序类型url,dist,comp将行解析到最小。

  • 如果输入文件作为第三个参数或没有写入/etc/apt/sources.list权限,则打印到stdout

  • 不支持[ options ] [ arch=amd64 ]类的[ options ] [ arch=amd64 ]
  • 丢弃disable default ,我要求用户指定要禁用的内容。
  • 我不喜欢上一个选项(9),因为我自己是故意混合回购。 所以他们应该被视为第三方存储库。

下载:完整的测试集。

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#*) *(?Pdeb(-src)?) *(?P(http://|ftp://|file://|cdrom:\[[a-zA-Z0-9 \-_().]*\])?\S*) (?P[a-zA-Z\-_]*) (?P[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) 

您可以使用add-apt-repository以非常简单的方式完成此操作。

例如,您可以添加proposed

 sudo add-apt-repository "http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc)-proposed restricted universe multiverse main" 

它会将debdeb-src行添加到/etc/apt/sources.list 。 但是会对源代码行进行评论。

如果使用-s参数运行add-apt-repository ,它将不会注释掉deb-src

您可以通过启用security

 sudo add-apt-repository "http://security.ubuntu.com/ubuntu/ $(lsb_release -sc)-security restricted universe multiverse main"