独立于运行bash脚本的位置解析文件

时间:2019-01-18 11:58:40

标签: linux bash unix

我有一个非常简单的脚本来读取位于不同目录中的文本文件:

IFS=$'\n' read -d '' -r -a urls < ../dat/urls.txt

从脚本所在的目录中运行脚本时,此方法很好用。/fetch_urls

但是,如果我从用户家或通过cron运行脚本,它将无法解析urls.txt文件。例如

/home/my-user/data-transfer/fetch_urls.sh

它失败并显示:

line 3: ../dat/urls.txt: No such file or directory

有某种方法可以使其正常工作,因此它始终可以正确解析urls.txt文件。还是我必须将urls.txt的位置作为参数传递?

2 个答案:

答案 0 :(得分:1)

您的文件是相对于脚本目录的。您可以通过以下方式获得它:

script_dir=$(dirname "$0")

您现在有两种解决方案:

  • 在访问cd之前,先urls.txt到该目录。我个人不这样做,因为它可能会破坏其他相对路径(例如,命令行上给出的路径)

  • 或者更好的是,在该路径的前面加上相对路径:

    IFS=$'\n' read -d '' -r -a urls < "$script_dir/../dat/urls.txt"
    

答案 1 :(得分:0)

首先,您需要解析已启动脚本的/opt/anaconda1anaconda2anaconda3(在您的示例中为class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate { var window: UIWindow? let gcmMessageIDKey = "message_id" static var DEVICE_ID = String() var msg_body = "" var msg_title = "" func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { UIApplication.shared.statusBarStyle = .lightContent FirebaseApp.configure() Messaging.messaging().delegate = self if #available(iOS 10.0, *) { // For iOS 10 display notification (sent via APNS) UNUserNotificationCenter.current().delegate = self let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization( options: authOptions, completionHandler: {_, _ in }) } else { let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) application.registerUserNotificationSettings(settings) } application.registerForRemoteNotifications() return true } func connectToFcm() { Messaging.messaging().shouldEstablishDirectChannel = true } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { if let refreshedToken = InstanceID.instanceID().token() { AppDelegate.DEVICE_ID = refreshedToken print("*********") print("InstanceID token: \(refreshedToken)") print("*********") }else{ print("Can't get token device") } connectToFcm() } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Failed to register for remote notifications with error: \(error)") } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { print(userInfo) guard let data: [String: Any] = userInfo as? [String: Any] else { return } let listData = data["notification"] as! String let jsonData = listData.data(using: .utf8) do { let decoder = JSONDecoder() let dataJson = try decoder.decode(DataNotif.self, from: jsonData!) msg_body = dataJson.body! msg_title = dataJson.title! createNotification(title: msg_title, body: msg_body) }catch{ print("error") } completionHandler(UIBackgroundFetchResult.newData) } // messaging func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) { if let token = InstanceID.instanceID().token() { AppDelegate.DEVICE_ID = token print("*********") print("Token Instance: \(token)") print("*********") } connectToFcm() } func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) { print("Received data message: \(remoteMessage.appData)") guard let data: [String: Any] = remoteMessage.appData as? [String: Any] else { return } let listData = data as! NSDictionary let jsonData = listData.data(using: .utf8) do { let decoder = JSONDecoder() let dataJson = try decoder.decode(DataNotif.self, from: jsonData!) msg_body = dataJson.body! msg_title = dataJson.title! createNotification(title: msg_title, body: msg_body) }catch{ print("error") } } func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert, .badge, .sound]) } func applicationDidBecomeActive(_ application: UIApplication) { UIApplication.shared.applicationIconBadgeNumber = 0 connectToFcm() } func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { completionHandler(.newData) } func applicationDidEnterBackground(_ application: UIApplication) { Messaging.messaging().shouldEstablishDirectChannel = false print("Disconnect FCM") } func createNotification(title: String, body: String) { let content = UNMutableNotificationContent() content.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil) content.body = NSString.localizedUserNotificationString(forKey: body, arguments: nil) content.sound = UNNotificationSound.default content.badge = NSNumber(integerLiteral: UIApplication.shared.applicationIconBadgeNumber + 1) let request = UNNotificationRequest.init(identifier: "pushNotif", content: content, trigger: nil) let center = UNUserNotificationCenter.current() center.add(request) } } )。

current directory

然后,您只需要在脚本中修正行即可:

fetch_urls.sh