活动介绍
file-type

.NET Core 3.1 Tee在Windows的Linux模拟实现

ZIP文件

下载需积分: 25 | 6KB | 更新于2025-01-04 | 137 浏览量 | 1 下载量 举报 收藏
download 立即下载
Tee是一个在.NET Core 3.1环境下开发的程序,旨在实现类似Linux中tee命令的基本功能。tee命令在Linux中用于从标准输入读取数据,并将其内容输出到标准输出和文件中。在.NET Core平台上,该程序提供了在Windows环境下运行Tee的基本功能,而无需依赖于GNU或其他类似环境。主要的功能是在不改变原有程序输出行为的基础上,将输出同时复制到控制台和指定的文件。 描述中提到的"myapplication.exe会将所有输出写入控制台",说明了Tee程序的默认行为是输出内容至控制台。而"myapplication.exe> file.txt会将所有输出写入文件,但不会写入控制台"则说明了在使用重定向操作时,程序会将输出重定向到文件中。这一点与在命令行环境下使用">"操作符的效果一致,即将指定的输出写入一个文件中。 描述中还提到了Tee程序与Linux中Tee命令的区别,主要体现在参数支持方面。Linux的tee命令支持将输出重定向到多个文件或输出流,以及追加到现有文件中,而不是覆盖。但在.NET Core实现的Tee程序中,它不支持除文件名之外的其他参数,并且如果指定的文件已存在,则原有内容会被覆盖,不支持追加输出。 在用法方面,描述中提到的"发球区域file.txt"是一种命令行的写法,其中"发球区域"可能是指"tee"的音译或者是命令行操作的一种描述。"myapplication.exe 2 >>&1 | 发球区域file.txt"的示例展示了如何将标准错误(通常用标识符2表示)合并到标准输出(标识符为1),然后通过管道(|)将输出传递给Tee程序。Tee程序会创建一个临时文件,将标准输出的内容写入临时文件中,同时保留一份到控制台的输出。 在技术实现上,Tee程序可能是使用C#语言开发,因为标签中提到了"C#"。C#是.NET Core支持的主要编程语言之一,开发者可以利用.NET Core提供的类库来实现标准输入输出的处理和文件操作。在C#中,可以通过System.Console类的Out属性来访问标准输出流,使用System.IO命名空间下的类如File来实现文件写入操作。 从压缩包子文件的文件名称列表中可知,该项目的源代码文件名可能为"Tee-main"。通常在一个C#项目中,"main"表示程序的入口点,也就是包含Main方法的类或文件,Main方法是程序的起始执行点。 综上所述,Tee程序是一个在.NET Core环境下实现Linux中tee功能的工具,它能在Windows环境下实现将程序输出同时写入控制台和文件的简单需求。尽管其功能与Linux中的tee命令相比有所简化,但它覆盖了在Windows环境下常见的使用场景,并且是一个学习和了解.NET Core标准输出和文件操作能力的好示例。

相关推荐

filetype

#!/bin/bash # ==================== 环境检测函数 ==================== check_environment() { local missing=() local errors=0 echo -e "\033[34m[环境检测] 开始检查系统依赖...\033[0m" # 检测必要软件 echo -n "检查 fpocket ...... " if ! command -v fpocket &> /dev/null; then echo -e "\033[31m缺失\033[0m" missing+=("fpocket") ((errors++)) else echo -e "\033[32m已安装\033[0m" fi echo -n "检查 AutoDock Vina ...... " if ! command -v vina &> /dev/null; then echo -e "\033[31m缺失\033[0m" missing+=("AutoDock Vina") ((errors++)) else echo -e "\033[32m已安装\033[0m" fi echo -n "检查 bc(计算器) ...... " if ! command -v bc &> /dev/null; then echo -e "\033[31m缺失\033[0m" missing+=("bc (计算器工具)") ((errors++)) else echo -e "\033[32m已安装\033[0m" fi # 检测WSL挂载点 echo -n "检查D盘挂载(/mnt/d) ...... " if [[ ! -d "/mnt/d" ]]; then echo -e "\033[31m未挂载\033[0m" missing+=("Windows D盘未挂载到/mnt/d") ((errors++)) else echo -e "\033[32m已挂载\033[0m" fi # 检测输入文件 echo -n "检查配体文件 ...... " if [[ ! -f "$LIGAND_FILE" ]]; then echo -e "\033[31m不存在\033[0m" missing+=("配体文件不存在: $LIGAND_FILE") ((errors++)) else echo -e "\033[32m存在\033[0m" fi echo -n "检查蛋白质目录 ...... " if [[ ! -d "$PROTEIN_DIR" ]]; then echo -e "\033[31m不存在\033[0m" missing+=("蛋白质目录不存在: $PROTEIN_DIR") ((errors++)) elif [[ -z "$(ls -A "$PROTEIN_DIR"/*.pdbqt 2>/dev/null)" ]]; then echo -e "\033[31m无PDBQT文件\033[0m" missing+=("蛋白质目录为空或没有PDBQT文件: $PROTEIN_DIR") ((errors++)) else echo -e "\033[32m正常\033[0m" fi # 如果有缺失项则报错 if [[ $errors -gt 0 ]]; then echo -e "\n\033[41m!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\033[0m" echo -e "\033[41m【致命错误】环境检测失败!缺少以下组件或配置:\033[0m" for item in "${missing[@]}"; do echo -e " - \033[31m$item\033[0m" done echo -e "\n\033[43m【解决方案】请执行以下操作:\033[0m" if [[ " ${missing[*]} " =~ "fpocket" ]]; then echo " - 安装fpocket: sudo apt install fpocket" fi if [[ " ${missing[*]} " =~ "AutoDock Vina" ]]; then echo " - 安装AutoDock Vina: sudo apt install autodock-vina" fi if [[ " ${missing[*]} " =~ "bc" ]]; then echo " - 安装bc计算器: sudo apt install bc" fi if [[ " ${missing[*]} " =~ "挂载" ]]; then echo " - 确认Windows D盘已挂载,或修改脚本中的WSL_D变量" echo " - 尝试手动挂载: sudo mkdir -p /mnt/d && sudo mount -t drvfs D: /mnt/d" fi if [[ " ${missing[*]} " =~ "配体文件" || " ${missing[*]} " =~ "蛋白质目录" ]]; then echo " - 检查文件路径是否正确,确保文件存在于WSL环境中" echo " - 当前配置的蛋白质目录: $PROTEIN_DIR" echo " - 当前配置的配体文件: $LIGAND_FILE" fi echo -e "\033[41m!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\033[0m\n" exit 1 fi echo -e "\033[42m[环境检测] 所有依赖项检查通过!\033[0m" return 0 } # ==================== 用户配置区域 ==================== WINDOWS_D="D:" # 原始Windows路径(仅参考) WSL_D="/mnt/d" # WSL挂载路径(必须修改为实际值) BASE_DIR="$WSL_D/Autodocksuite" # 基础工作目录 # 输入输出目录 PROTEIN_DIR="$BASE_DIR/proteins" # 蛋白质目录 LIGAND_FILE="$BASE_DIR/Afatinib.pdbqt" # 配体文件 FPOCKET_DIR="$BASE_DIR/fpocket_results" # fpocket结果目录 OUTPUT_DIR="$BASE_DIR/output" # 输出目录 # ==================== 脚本主体 ==================== # 首先执行环境检测 check_environment || exit 1 # 创建目录结构 mkdir -p "$FPOCKET_DIR" "$OUTPUT_DIR" if [[ $? -ne 0 ]]; then echo -e "\033[41m【致命错误】无法创建输出目录!\033[0m" echo -e "请检查路径权限: $OUTPUT_DIR" exit 1 fi LOG_FILE="$OUTPUT_DIR/docking_log_$(date +%Y%m%d_%H%M%S).txt" # 记录开始信息 echo "=== 分子对接工作流程开始 ===" | tee -a "$LOG_FILE" echo "开始时间: $(date '+%Y-%m-%d %H:%M:%S')" | tee -a "$LOG_FILE" echo "蛋白质目录: $PROTEIN_DIR" | tee -a "$LOG_FILE" echo "蛋白质数量: $(ls "$PROTEIN_DIR"/*.pdbqt | wc -l)" | tee -a "$LOG_FILE" echo "配体文件: $LIGAND_FILE" | tee -a "$LOG_FILE" # 步骤1: fpocket口袋预测 echo -e "\n\033[44m[阶段1] 蛋白质结合口袋预测\033[0m" | tee -a "$LOG_FILE" protein_count=0 processed_files=0 for protein in "$PROTEIN_DIR"/*.pdbqt; do # 检查文件是否存在 if [[ ! -f "$protein" ]]; then continue fi base_name=$(basename "$protein" .pdbqt) echo "处理: $base_name" | tee -a "$LOG_FILE" # 临时转换格式供fpocket使用 if ! grep -E '^ATOM|^HETATM' "$protein" > "$FPOCKET_DIR/temp_$base_name.pdb"; then echo -e "\033[33m[警告] $base_name PDBQT转换PDB失败,跳过\033[0m" | tee -a "$LOG_FILE" continue fi # 运行fpocket预测口袋 echo "执行fpocket预测..." | tee -a "$LOG_FILE" if ! fpocket -f "$FPOCKET_DIR/temp_$base_name.pdb" -o "$FPOCKET_DIR/$base_name" >> "$LOG_FILE" 2>&1; then echo -e "\033[33m[警告] $base_name 口袋预测失败,跳过\033[0m" | tee -a "$LOG_FILE" rm -f "$FPOCKET_DIR/temp_$base_name.pdb" continue fi # 清理临时文件 rm -f "$FPOCKET_DIR/temp_$base_name.pdb" ((protein_count++)) ((processed_files++)) # 进度报告 if ((processed_files % 50 == 0)); then echo -e "\033[45m[进度] 已处理 $processed_files 个蛋白质\033[0m" | tee -a "$LOG_FILE" fi done if [[ $protein_count -eq 0 ]]; then echo -e "\033[41m【致命错误】没有成功处理任何蛋白质!\033[0m" | tee -a "$LOG_FILE" exit 1 fi echo "fpocket口袋预测完成! 成功处理 $protein_count 个蛋白质" | tee -a "$LOG_FILE" # 步骤2: 分子对接 echo -e "\n\033[44m[阶段2] 分子对接处理\033[0m" | tee -a "$LOG_FILE" SUMMARY_FILE="$OUTPUT_DIR/summary_results.csv" echo "蛋白质,最佳亲和力(kcal/mol),口袋中心X,口袋中心Y,口袋中心Z,盒子尺寸" > "$SUMMARY_FILE" processed_count=0 success_count=0 error_count=0 for protein in "$PROTEIN_DIR"/*.pdbqt; do if [[ ! -f "$protein" ]]; then continue fi base_name=$(basename "$protein" .pdbqt) pocket_info="$FPOCKET_DIR/$base_name/temp_${base_name}_info.txt" if [[ ! -f "$pocket_info" ]]; then echo -e "\033[33m[警告] $base_name 无口袋信息,跳过\033[0m" | tee -a "$LOG_FILE" echo "$base_name,NA,NA,NA,NA,NA" >> "$SUMMARY_FILE" ((error_count++)) continue fi # 解析口袋信息 - 更健壮的方法 best_pocket=$(grep "^Pocket " "$pocket_info" 2>/dev/null | sort -k6 -nr | head -1) pocket_num=$(grep "^Pocket " "$pocket_info" | sort -k6 -nr | head -1 | awk '{print $2}') center_line=$(grep -A1 "Pocket $pocket_num" "$pocket_info" | grep "Center :") if [[ -z "$best_pocket" ]]; then echo -e "\033[33m[警告] $base_name 无有效口袋,跳过\033[0m" | tee -a "$LOG_FILE" echo "$base_name,NA,NA,NA,NA,NA" >> "$SUMMARY_FILE" ((error_count++)) continue fi if [[ -z "$center_line" ]]; then echo -e "\033[33m[警告] $base_name 无中心坐标信息,跳过\033[0m" continue fi # 提取参数 - 使用awk确保健壮性 cx=$(echo "$center_line" | awk '{print $3}') cy=$(echo "$center_line" | awk '{print $4}') cz=$(echo "$center_line" | awk '{print $5}') size=$(echo "$best_pocket" | awk '{print $11}') volume=$(grep -A10 "Pocket $pocket_num" "$pocket_info" | grep -m1 "Volume :" | awk '{print $3}') box_size=$(echo "scale=2; e( l($volume)/3 ) + 5" | bc -l 2>/dev/null || echo 20) # 验证数值有效性 if ! [[ "$cx" =~ ^-?[0-9.]+$ ]] || ! [[ "$cy" =~ ^-?[0-9.]+$ ]] || ! [[ "$cz" =~ ^-?[0-9.]+$ ]] || ! [[ "$size" =~ ^[0-9.]+$ ]]; then echo -e "\033[33m[警告] $base_name 口袋参数无效,跳过\033[0m" | tee -a "$LOG_FILE" echo "$base_name,INVALID,NA,NA,NA,NA" >> "$SUMMARY_FILE" ((error_count++)) continue fi # 计算盒子尺寸(在口袋大小基础上增加padding) if [[ -z "$box_size" ]]; then box_size=20.0 echo -e "\033[33m[警告] $base_name 盒子尺寸计算失败,使用默认值20Å\033[0m" | tee -a "$LOG_FILE" fi # 确保盒子尺寸在合理范围内 box_size=$(echo "$box_size" | awk -v min=15 -v max=30 \ '{if ($1 < min) print min; else if ($1 > max) print max; else print $1}') # 创建输出子目录 protein_output_dir="$OUTPUT_DIR/$base_name" mkdir -p "$protein_output_dir" # 运行AutoDock Vina echo "对接: $base_name | 中心($cx, $cy, $cz) | 盒子: ${box_size}Å" | tee -a "$LOG_FILE" vina_cmd=( vina --receptor "$protein" --ligand "$LIGAND_FILE" --center_x "$cx" --center_y "$cy" --center_z "$cz" --size_x "$box_size" --size_y "$box_size" --size_z "$box_size" --exhaustiveness 8 --num_modes 5 --out "$protein_output_dir/${base_name}_out.pdbqt" --log "$protein_output_dir/${base_name}_log.txt" ) if ! "${vina_cmd[@]}" >> "$LOG_FILE" 2>&1; then echo -e "\033[31m[错误] $base_name 对接失败\033[0m" | tee -a "$LOG_FILE" echo "$base_name,FAILED,$cx,$cy,$cz,$box_size" >> "$SUMMARY_FILE" ((error_count++)) else # 提取最佳亲和力 - 更健壮的提取方法 log_file="$protein_output_dir/${base_name}_log.txt" affinity=$(awk '/^-----+/ {flag=1} flag && /^ 1 / {print $2; exit}' "$log_file") if [[ -n "$affinity" && "$affinity" =~ ^-?[0-9.]+$ ]]; then echo "$base_name,$affinity,$cx,$cy,$cz,$box_size" >> "$SUMMARY_FILE" ((success_count++)) echo -e "\033[32m[成功] $base_name 对接完成,亲和力: $affinity kcal/mol\033[0m" | tee -a "$LOG_FILE" else echo -e "\033[31m[错误] $base_name 亲和力解析失败\033[0m" | tee -a "$LOG_FILE" echo "$base_name,PARSE_ERROR,$cx,$cy,$cz,$box_size" >> "$SUMMARY_FILE" ((error_count++)) fi fi # 进度报告 ((processed_count++)) if ((processed_count % 20 == 0)); then echo -e "\033[45m[进度] 已处理 $processed_count 个 | 成功: $success_count | 失败: $error_count\033[0m" | tee -a "$LOG_FILE" fi done # 最终统计 total_proteins=$(ls "$PROTEIN_DIR"/*.pdbqt | wc -l) success_rate=$(echo "scale=2; $success_count * 100 / $total_proteins" | bc) # 结果报告 echo -e "\n\033[42m[完成] 任务执行完毕\033[0m" | tee -a "$LOG_FILE" echo "总处理: $total_proteins 个蛋白质" | tee -a "$LOG_FILE" echo "成功对接: $success_count 个 (成功率: ${success_rate}%)" | tee -a "$LOG_FILE" echo "失败数量: $error_count 个" | tee -a "$LOG_FILE" # 显示最佳结果 if [[ $success_count -gt 0 ]]; then echo -e "\n\033[44m最佳结合结果(亲和力越小越好):\033[0m" | tee -a "$LOG_FILE" grep -vE "NA|FAILED|INVALID|PARSE_ERROR" "$SUMMARY_FILE" | \ sort -t, -k2 -n | \ head -10 | \ awk -F, '{printf "%-20s %10.2f kcal/mol\n", $1, $2}' | \ tee -a "$LOG_FILE" else echo -e "\n\033[41m警告: 没有成功对接的蛋白质!\033[0m" | tee -a "$LOG_FILE" fi # 最终路径提示 echo -e "\n\033[43m输出文件位置:\033[0m" | tee -a "$LOG_FILE" echo "结果汇总: $SUMMARY_FILE" | tee -a "$LOG_FILE" echo "详细日志: $LOG_FILE" | tee -a "$LOG_FILE" echo "对接结果目录: $OUTPUT_DIR" | tee -a "$LOG_FILE" echo "fpocket结果目录: $FPOCKET_DIR" | tee -a "$LOG_FILE" # 退出状态 if [[ $success_count -eq 0 ]]; then exit 2 elif [[ $error_count -gt 0 ]]; then exit 1 else exit 0 fi这个代码运行结束后,每个蛋白都检测不到蛋白口袋,这是为什么

thonxie
  • 粉丝: 41
上传资源 快速赚钱