Mac下IDEA+Tomcat error=13 Permission denied

本文解决在MacOSX系统中使用IDEA启动Tomcat时遇到的error=13 Permission denied错误。通过在终端中更改Tomcat bin目录下所有.sh文件的权限为777,成功解决了IDEA运行Tomcat时的权限不足问题。
错误日志:
下午1:47:18 Error running 未命名: Cannot run program "/Users/J/Documents/kk/Tomcat/apache-tomcat-9.0.0.M17/bin/catalina.sh" 
(in directory "/Users/J/Documents/kk/Tomcat/apache-tomcat-9.0.0.M17/bin"): error=13, Permission denied
解决办法:权限不足,Mac授权即可
打开终端,进入tomcat\bin目录,然后执行:
chmod 777 *.sh

本文转载自简书文章:Mac OS X下IDEA+Tomcat error=13 Permission denied解决

<think>我们遇到的问题是在Kotlin中,在Android 12及以上系统中运行adb程序时出现"error=13, permission denied"。这个错误通常表示应用没有足够的权限执行操作。根据引用内容,我们可以分析出几个可能的原因和解决方案: 1. **权限问题**:在Android中,执行外部程序或访问文件系统需要相应的权限。特别是Android 6.0(API 23)以后,危险权限需要运行时申请。另外,从Android 11(API 30)开始,对文件访问权限有更严格的限制。 2. **ADB命令的执行**:在非root设备上,普通应用无法执行`adb`命令,因为`adb`通常位于系统目录(如`/system/bin/adb`),需要root权限才能执行。在Android 4.4之后,即使尝试使用`su`命令获取root权限也可能失败(如引用[3]所述)。 3. **NDK相关错误**:引用[1]中提到的错误也可能与文件权限有关,比如NDK工具链中的某些文件没有执行权限。 4. **文件系统权限**:如果试图执行某个文件,该文件可能没有可执行权限(对于Linux系统,错误13是权限拒绝)。 针对在Android 12+上运行adb命令遇到权限拒绝的问题,我们可以考虑以下解决方案: ### 1. 检查并申请运行时权限(如果涉及存储访问) 在AndroidManifest.xml中声明需要的权限,并在运行时申请。例如,如果涉及到外部存储,需要申请`READ_EXTERNAL_STORAGE`或`WRITE_EXTERNAL_STORAGE`(在Android 10及以下)或者使用MediaStore API(Android 10及以上)。但是,adb命令的执行通常不是存储权限问题,而是执行权限问题。 ### 2. 确保可执行文件有执行权限 如果我们试图执行的是自己复制到应用数据目录的二进制文件(比如我们打包在assets中的adb二进制文件),那么我们需要确保该文件有执行权限。在复制文件后,使用`File.setExecutable(true)`设置执行权限。 示例代码: ```kotlin try { // 假设我们从assets复制adb二进制文件到应用内部存储 val destFile = File(filesDir, "adb") assets.open("adb").use { input -> FileOutputStream(destFile).use { output -> input.copyTo(output) } } // 设置可执行权限 destFile.setExecutable(true) } catch (e: Exception) { e.printStackTrace() } ``` ### 3. 避免执行系统ADB(通常不可行) 除非是系统应用或者有root权限,否则无法执行系统目录下的adb命令。因此,通常的做法是将adb二进制文件(针对目标设备架构编译)打包到应用的assets中,然后在运行时复制到应用内部目录,并赋予执行权限,再执行该二进制文件。 ### 4. 使用ProcessBuilder执行命令 使用`Runtime.getRuntime().exec()`或`ProcessBuilder`来执行命令,并确保命令路径正确,且有执行权限。同时,注意处理输入输出流,避免阻塞。 ### 5. 针对Android 12+的适配 从Android 11开始,应用无法直接执行系统二进制文件(除非是系统应用)。因此,如果我们需要执行adb命令,唯一的办法是将adb二进制文件放在应用内部存储中执行。同时,需要注意: - 二进制文件需要针对不同CPU架构编译,并在应用中包含相应的版本(如armeabi-v7a, arm64-v8a, x86等)。 - 在复制文件后,设置可执行权限。 ### 6. 考虑使用Shizuku或Root权限 如果应用需要执行系统级命令,可以考虑使用Shizuku(需要用户授权)或者引导用户root设备。但大多数情况下,普通应用无法做到。 ### 完整示例(执行内部存储中的adb二进制文件) 1. **准备adb二进制文件**:针对不同架构编译adb,并放入app/src/main/assets目录(可以创建子目录如adb/arm64-v8a/adb,然后在运行时根据设备架构选择复制)。 2. **复制并设置权限**: ```kotlin fun copyAdbBinary(context: Context) { val abi = Build.SUPPORTED_ABIS[0] // 主ABI val assetPath = "adb/$abi/adb" val destFile = File(context.filesDir, "adb") try { context.assets.open(assetPath).use { input -> FileOutputStream(destFile).use { output -> input.copyTo(output) } } destFile.setExecutable(true) } catch (e: Exception) { e.printStackTrace() } } ``` 3. **执行命令**: ```kotlin fun runAdbCommand(context: Context, command: String): String { val adbFile = File(context.filesDir, "adb") val process = ProcessBuilder(adbFile.absolutePath, command).start() // 读取输出 val reader = BufferedReader(InputStreamReader(process.inputStream)) val output = StringBuilder() var line: String? while (reader.readLine().also { line = it } != null) { output.append(line).append('\n') } process.waitFor() return output.toString() } ``` 4. **注意**:在Android 12+,即使这样执行,也可能因为安全限制而失败(特别是涉及网络等操作)。另外,adb命令需要连接adbd服务,通常只能在root设备上使用。 ### 结论 在非root设备上,普通应用无法执行系统自带的adb命令。如果应用需要执行adb命令,通常需要设备root,或者使用Shizuku等方案。另外,如果应用是自己编译的adb二进制文件,并且命令不涉及系统操作(比如只是模拟部分功能),那么可以尝试执行,但通常adb命令需要与adbd服务交互,所以很难在非root环境运行。 对于大多数应用场景,应该避免执行adb命令,而是使用Android SDK提供的API来实现功能。 §§相关问题§§ 1. 如何在非root设备上执行需要root权限的命令? 2. Android 12+中如何安全地执行外部二进制文件? 3. 如何为Android应用编译跨CPU架构的二进制文件? </think>### Kotlin在Android 12+系统中运行adb程序出现`error=13, permission denied`的解决方案 在Android 12+系统中执行adb命令时出现`error=13`错误,表示应用缺乏执行系统级操作的权限。以下是完整解决方案: #### 1. **检查并申请运行时权限(必需)** 在AndroidManifest.xml中添加权限声明: ```xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Android 11+ 需要额外声明 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" /> ``` 在Kotlin代码中动态申请权限: ```kotlin private val REQUEST_CODE = 123 fun checkPermissions(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (!Environment.isExternalStorageManager()) { val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) intent.data = Uri.parse("package:${context.packageName}") startActivity(intent) } } else { ActivityCompat.requestPermissions( this, arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE ), REQUEST_CODE ) } } ``` #### 2. **使用ProcessBuilder执行命令(安全方式)** ```kotlin fun runAdbCommand(command: String): String { return try { val process = ProcessBuilder() .command("/system/bin/sh", "-c", command) .redirectErrorStream(true) .start() val output = process.inputStream.bufferedReader().use { it.readText() } process.waitFor() output } catch (e: IOException) { "Error: ${e.message}" } catch (e: InterruptedException) { "Process interrupted" } } // 使用示例 val result = runAdbCommand("adb devices") Log.d("ADB_OUTPUT", result) ``` #### 3. **处理Android 12+的权限限制** 针对Android 12+的隐私限制: ```kotlin if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // 检查ADB调试权限 if (!Environment.isDevelopmentSettingsEnabled()) { val intent = Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS) startActivity(intent) } } ``` #### 4. **共享UID系统签名(仅限系统应用)** 在AndroidManifest.xml中添加: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:sharedUserId="android.uid.system"> <!-- 需要系统平台签名 --> </manifest> ``` #### 5. **替代方案:使用ADB over WiFi** ```kotlin fun connectAdbOverWifi(ip: String, port: Int) { runAdbCommand("adb tcpip $port") runAdbCommand("adb connect $ip:$port") } ``` #### 关键注意事项: 1. **权限模型变更** Android 11+引入Scoped Storage,限制访问外部存储路径: $$ \text{权限检查} = \begin{cases} \text{MANAGE\_EXTERNAL\_STORAGE} & \text{API ≥ 30} \\ \text{READ/WRITE\_EXTERNAL\_STORAGE} & \text{API < 30} \end{cases} $$ 2. **SELinux策略限制** 在系统级操作中,检查SELinux上下文是否正确: ```bash adb shell ls -Z /system/bin/adb # 正确输出: u:object_r:adb_exec:s0 ``` 3. **ADB二进制权限** 确保adb二进制有执行权限(权限位应为`755`): ```kotlin File("/system/bin/adb").setExecutable(true) ``` > ⚠️ **重要提示**:普通应用无法直接执行系统级adb命令,需要系统签名或root权限。优先考虑使用Android SDK提供的API替代直接adb命令调用[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值