shell学习心得笔记系列二 gradlew.sh 源码脚本解析

#!/usr/bin/env sh

#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
# while 递归get 当前执行文件的实际文件名
while [ -h "$PRG" ]; do
  ls=$(ls -ld "$PRG")
  link=$(expr "$ls" : '.*-> \(.*\)$')
  if expr "$link" : '/.*' >/dev/null; then
    PRG="$link"
  else
    # 如果是链接,进一步用 prg中的dir拼接 link_file_name
    PRG=$(dirname "$PRG")"/$link"
  fi
done
# 保存当前文件
SAVED="$(pwd)"
# 切换到文件的实际地址
cd "$(dirname \"$PRG\")/" >/dev/null
# 保存文件实际dir为APP_HOME
APP_HOME="$(pwd -P)"
# 回到原文件夹
cd "$SAVED" >/dev/null

# 设置gradle name
APP_NAME="Gradle"
APP_BASE_NAME=$(basename "$0")

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# 设置执行该脚本的jvm参数
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
# 错误 警告的log处理 
warn() {
  echo "$*"
}

die() {
  echo
  echo "$*"
  echo
  exit 1
}

# OS specific support (must be 'true' or 'false').
# 判断操作系统,默认值false
cygwin=false
msys=false
darwin=false
nonstop=false
case "$(uname)" in
CYGWIN*)
  cygwin=true
  ;;
Darwin*)
  darwin=true
  ;;
MINGW*)
  msys=true
  ;;
NONSTOP*)
  nonstop=true
  ;;
esac

# 设置本地gradle.jar的CLASSPATH
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
# 检查 java的环境、命令
if [ -n "$JAVA_HOME" ]; then
  if [ -x "$JAVA_HOME/jre/sh/java" ]; then
    # IBM's JDK on AIX uses strange locations for the executables
    JAVACMD="$JAVA_HOME/jre/sh/java"
  else
    JAVACMD="$JAVA_HOME/bin/java"
  fi
  if [ ! -x "$JAVACMD" ]; then
    die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
  fi
else
  JAVACMD="java"
  # 报错=>die
  which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.

# 检查操作系统类型,如果不是 Cygwin、Darwin 或 NonStop
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then
# 获取系统支持的最大文件描述符数量,保存到 MAX_FD_LIMIT 变量中
  MAX_FD_LIMIT=$(ulimit -H -n)
  if [ $? -eq 0 ]; then
  # 如果上一条命令ulimit -H -n的返回值为0
    if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
    # 如果用户将 MAX_FD 设置为 "maximum" 或 "max",则使用系统支持的最大文件描述符数量
      MAX_FD="$MAX_FD_LIMIT"
    fi
    # 否则使用用户设置的 MAX_FD。
    ulimit -n $MAX_FD
    if [ $? -ne 0 ]; then
      # 执行错误 报错
      warn "Could not set maximum file descriptor limit: $MAX_FD"
    fi
  else
    warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
  fi
fi

# For Darwin, add options to specify how the application appears in the dock
# 如果是 macOS 则设置 Gradle 的启动参数用于指定应用程序在 macOS Dock 栏中显示的名称和图标
if $darwin; then
  GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin or MSYS, switch paths to Windows format before running java
# 在Cygwin或MSYS下将路径转换成Windows格式后运行Java程序的。unix格式和windows路径格式不兼容
# cygpath命令将Unix格式的路径转换为Windows格式的路径
if [ "$cygwin" = "true" -o "$msys" = "true" ]; then
# 转换 APP_HOME CLASSPATH JAVACMD
  APP_HOME=$(cygpath --path --mixed "$APP_HOME")
  CLASSPATH=$(cygpath --path --mixed "$CLASSPATH")
  JAVACMD=$(cygpath --unix "$JAVACMD")

  # We build the pattern for arguments to be converted via cygpath
  # 使用find命令查找根目录下的所有目录,并使用正则表达式构建一个模式pattern
  ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null)
  SEP=""
  # 该模式用于在下面的循环中将命令行参数转换为Windows格式的路径
  for dir in $ROOTDIRSRAW; do
    ROOTDIRS="$ROOTDIRS$SEP$dir"
    # 用 | 字符作为分隔符,将dir连接成一个正则表达式的模式
    SEP="|"
  done
  # 所有以 ROOTDIRS 变量中列出的目录路径开头的路径都将被匹配
  OURCYGPATTERN="(^($ROOTDIRS))"
  # Add a user-defined pattern to the cygpath arguments
  # 如果有GRADLE定义的CYGPATTERN
  if [ "$GRADLE_CYGPATTERN" != "" ]; then
    # 在添加一个新模式
    OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
  fi
  # Now convert the arguments - kludge to limit ourselves to /bin/sh
  i=0
  # 使用case语句将转换后的参数重新设置为命令行参数
  for arg in "$@"; do
  # 遍历命令行参数
    # 使用正则表达式将其与OURCYGPATTERN匹配
    # -c 选项用来统计匹配行的数量。- 表示从标准输入中读取数据
    CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -)
    # 匹配以横线字符“-”开头的arg 的数量
    CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option

    if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition
    # $CHECK 不等于 0 && $CHECK2 等于 0 表明  $arg 的路径部分是一个 Windows 目录
      eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg")
    else
      # 其他参数 编号 赋值给临时变量args0-argsN
      eval $(echo args$i)="\"$arg\""
    fi
    # 计数 参数数量
    i=$((i + 1))
  done
  case $i in
  # 重置对应位置的参数——如果经过了cygpath转换
  0) set -- ;;
  1) set -- "$args0" ;;
  2) set -- "$args0" "$args1" ;;
  3) set -- "$args0" "$args1" "$args2" ;;
  4) set -- "$args0" "$args1" "$args2" "$args3" ;;
  5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
  6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
  7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
  8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
  9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
  esac
fi

# Escape application args
# 该函数的目的是将传入的参数逐个输出,并在每个参数两端添加单引号,以便在脚本中正确处理包含空格和其他特殊字符的参数。
save() {
  for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done
  echo " "
}

APP_ARGS=$(save "$@")

# Collect all arguments for the java command, following the shell quoting and substitution rules
# 根据参数 执行org.gradle.wrapper.GradleWrapperMain 
#eval命令设置变量的语句 [DEFAULT_JVM_OPTS、JAVA_OPTS、GRADLE_OPTS、APP_BASE_NAME、CLASSPATH]组合成一个命令行参数,
# 并将其与原始的命令行参数("$@")合并
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
  cd "$(dirname "$0")"
fi
# 执行java 命令
# ava应用程序的主类来运行Gradle Wrapper
exec "$JAVACMD" "$@"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值