compare.sh
                        
                             · 718 B · Bash
                        
                    
                    
                      
                        Неформатований
                      
                    
                      
                    
                        
                          
                        
                    
                    
                
                
                
            #!/usr/bin/env bash
#
# compare_packages.sh
#
# Compare package lists from two systems:
#   anduinos-packages.txt
#   ubuntu-24-packages.txt
# Ensure both files exist
if [[ ! -f "anduinos-packages.txt" || ! -f "ubuntu-24-packages.txt" ]]; then
  echo "Error: One or both package list files are missing."
  echo "Please make sure anduinos-packages.txt and ubuntu-24-packages.txt are present."
  exit 1
fi
echo "===== Packages installed on anduinos but NOT on ubuntu ====="
comm -23 <(sort anduinos-packages.txt) <(sort ubuntu-24-packages.txt)
echo
echo "===== Packages installed on ubuntu but NOT on anduinos ====="
comm -13 <(sort anduinos-packages.txt) <(sort ubuntu-24-packages.txt)
echo
echo "Comparison done."
                | 1 | #!/usr/bin/env bash | 
| 2 | # | 
| 3 | # compare_packages.sh | 
| 4 | # | 
| 5 | # Compare package lists from two systems: | 
| 6 | # anduinos-packages.txt | 
| 7 | # ubuntu-24-packages.txt | 
| 8 | |
| 9 | # Ensure both files exist | 
| 10 | if [[ ! -f "anduinos-packages.txt" || ! -f "ubuntu-24-packages.txt" ]]; then | 
| 11 | echo "Error: One or both package list files are missing." | 
| 12 | echo "Please make sure anduinos-packages.txt and ubuntu-24-packages.txt are present." | 
| 13 | exit 1 | 
| 14 | fi | 
| 15 | |
| 16 | echo "===== Packages installed on anduinos but NOT on ubuntu =====" | 
| 17 | comm -23 <(sort anduinos-packages.txt) <(sort ubuntu-24-packages.txt) | 
| 18 | |
| 19 | echo | 
| 20 | echo "===== Packages installed on ubuntu but NOT on anduinos =====" | 
| 21 | comm -13 <(sort anduinos-packages.txt) <(sort ubuntu-24-packages.txt) | 
| 22 | |
| 23 | echo | 
| 24 | echo "Comparison done." | 
| 25 | 
                    
                        
                        export.sh
                        
                             · 126 B · Bash
                        
                    
                    
                      
                        Неформатований
                      
                    
                      
                    
                        
                          
                        
                    
                    
                
                
                
            dpkg-query -f '${binary:Package}\n' -W > anduinos-packages.txt
dpkg-query -f '${binary:Package}\n' -W > ubuntu-24-packages.txt
                | 1 | dpkg-query -f '${binary:Package}\n' -W > anduinos-packages.txt | 
| 2 | dpkg-query -f '${binary:Package}\n' -W > ubuntu-24-packages.txt | 
                    
                        
                        visualize.py
                        
                             · 3.0 KiB · Python
                        
                    
                    
                      
                        Неформатований
                      
                    
                      
                    
                        
                          
                        
                    
                    
                
                
                
            import subprocess
from collections import defaultdict
def list_installed_packages():
    """获取所有已安装的包列表。"""
    result = subprocess.run(
        ["dpkg-query", "-f", "${binary:Package}\n", "-W"],
        stdout=subprocess.PIPE,
        text=True
    )
    return result.stdout.strip().split("\n")
def get_package_dependencies(package):
    """查询单个包的直接依赖项。"""
    result = subprocess.run(
        ["apt-cache", "depends", package],
        stdout=subprocess.PIPE,
        text=True
    )
    dependencies = []
    for line in result.stdout.strip().split("\n"):
        if line.strip().startswith("Depends:"):
            dep = line.split(":", 1)[1].strip()
            dep = dep.split(":")[0]  # 去掉冒号后的部分
            dependencies.append(dep)
    return dependencies
def build_dependency_graph(packages):
    """构建包的依赖关系图。"""
    totalPackages = len(packages)
    processedPackages = 0
    graph = defaultdict(list)
    for package in packages:
        dependencies = get_package_dependencies(package)
        for dep in dependencies:
            print(f"{package} -> {dep}")
            graph[package].append(dep)
        processedPackages += 1
        print(f"已处理 {processedPackages}/{totalPackages} 个包")
    return graph
def remove_redundant_edges(graph):
    """去除冗余的边。"""
    def dfs(node, visited):
        if node in visited:
            return visited[node]
        visited[node] = set()
        for neighbor in graph[node]:
            visited[node].update(dfs(neighbor, visited))
        visited[node].add(node)
        return visited[node]
    # 创建 graph 的静态副本来避免动态修改引发问题
    nodes = list(graph.keys())
    reachable = {}
    for node in nodes:  # 这里使用静态副本
        dfs(node, reachable)
    minimal_graph = defaultdict(list)
    for node in nodes:  # 再次使用静态副本
        direct_deps = set(graph[node])
        for dep in graph[node]:
            direct_deps -= reachable[dep]
        minimal_graph[node] = list(direct_deps)
    return minimal_graph
def generate_mermaid_graph(graph):
    """生成 Mermaid 图表的语法。"""
    lines = ["stateDiagram-v2"]
    for package, dependencies in graph.items():
        for dep in dependencies:
            lines.append(f"    {package} --> {dep}")
    return "\n".join(lines)
def main():
    print("正在获取已安装的包...")
    packages = list_installed_packages()
    print("正在构建依赖图...")
    graph = build_dependency_graph(packages)
    print("正在去除冗余边...")
    minimal_graph = remove_redundant_edges(graph)
    print("正在生成 Mermaid 图表语法...")
    mermaid_graph = generate_mermaid_graph(minimal_graph)
    with open("dependency_graph.mmd", "w") as file:
        file.write("---\n")
        file.write("title: APT Dependency Graph\n")
        file.write("---\n\n")
        file.write(mermaid_graph)
    print("Mermaid 图表已生成并保存为 dependency_graph.mmd")
if __name__ == "__main__":
    main()
                | 1 | import subprocess | 
| 2 | from collections import defaultdict | 
| 3 | |
| 4 | def list_installed_packages(): | 
| 5 | """获取所有已安装的包列表。""" | 
| 6 | result = subprocess.run( | 
| 7 | ["dpkg-query", "-f", "${binary:Package}\n", "-W"], | 
| 8 | stdout=subprocess.PIPE, | 
| 9 | text=True | 
| 10 | ) | 
| 11 | return result.stdout.strip().split("\n") | 
| 12 | |
| 13 | def get_package_dependencies(package): | 
| 14 | """查询单个包的直接依赖项。""" | 
| 15 | result = subprocess.run( | 
| 16 | ["apt-cache", "depends", package], | 
| 17 | stdout=subprocess.PIPE, | 
| 18 | text=True | 
| 19 | ) | 
| 20 | dependencies = [] | 
| 21 | for line in result.stdout.strip().split("\n"): | 
| 22 | if line.strip().startswith("Depends:"): | 
| 23 | dep = line.split(":", 1)[1].strip() | 
| 24 | dep = dep.split(":")[0] # 去掉冒号后的部分 | 
| 25 | dependencies.append(dep) | 
| 26 | return dependencies | 
| 27 | |
| 28 | def build_dependency_graph(packages): | 
| 29 | """构建包的依赖关系图。""" | 
| 30 | totalPackages = len(packages) | 
| 31 | processedPackages = 0 | 
| 32 | graph = defaultdict(list) | 
| 33 | for package in packages: | 
| 34 | dependencies = get_package_dependencies(package) | 
| 35 | for dep in dependencies: | 
| 36 | print(f"{package} -> {dep}") | 
| 37 | graph[package].append(dep) | 
| 38 | processedPackages += 1 | 
| 39 | print(f"已处理 {processedPackages}/{totalPackages} 个包") | 
| 40 | return graph | 
| 41 | |
| 42 | def remove_redundant_edges(graph): | 
| 43 | """去除冗余的边。""" | 
| 44 | def dfs(node, visited): | 
| 45 | if node in visited: | 
| 46 | return visited[node] | 
| 47 | visited[node] = set() | 
| 48 | for neighbor in graph[node]: | 
| 49 | visited[node].update(dfs(neighbor, visited)) | 
| 50 | visited[node].add(node) | 
| 51 | return visited[node] | 
| 52 | |
| 53 | # 创建 graph 的静态副本来避免动态修改引发问题 | 
| 54 | nodes = list(graph.keys()) | 
| 55 | reachable = {} | 
| 56 | for node in nodes: # 这里使用静态副本 | 
| 57 | dfs(node, reachable) | 
| 58 | |
| 59 | minimal_graph = defaultdict(list) | 
| 60 | for node in nodes: # 再次使用静态副本 | 
| 61 | direct_deps = set(graph[node]) | 
| 62 | for dep in graph[node]: | 
| 63 | direct_deps -= reachable[dep] | 
| 64 | minimal_graph[node] = list(direct_deps) | 
| 65 | return minimal_graph | 
| 66 | |
| 67 | def generate_mermaid_graph(graph): | 
| 68 | """生成 Mermaid 图表的语法。""" | 
| 69 | lines = ["stateDiagram-v2"] | 
| 70 | for package, dependencies in graph.items(): | 
| 71 | for dep in dependencies: | 
| 72 | lines.append(f" {package} --> {dep}") | 
| 73 | return "\n".join(lines) | 
| 74 | |
| 75 | def main(): | 
| 76 | print("正在获取已安装的包...") | 
| 77 | packages = list_installed_packages() | 
| 78 | |
| 79 | print("正在构建依赖图...") | 
| 80 | graph = build_dependency_graph(packages) | 
| 81 | |
| 82 | print("正在去除冗余边...") | 
| 83 | minimal_graph = remove_redundant_edges(graph) | 
| 84 | |
| 85 | print("正在生成 Mermaid 图表语法...") | 
| 86 | mermaid_graph = generate_mermaid_graph(minimal_graph) | 
| 87 | |
| 88 | with open("dependency_graph.mmd", "w") as file: | 
| 89 | file.write("---\n") | 
| 90 | file.write("title: APT Dependency Graph\n") | 
| 91 | file.write("---\n\n") | 
| 92 | file.write(mermaid_graph) | 
| 93 | |
| 94 | print("Mermaid 图表已生成并保存为 dependency_graph.mmd") | 
| 95 | |
| 96 | if __name__ == "__main__": | 
| 97 | main() | 
| 98 |