Как я могу связать .sh файлы с Cygwin?

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

blockquote>

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.
blockquote>

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

48
задан Csaba 14 October 2018 в 00:23
поделиться

9 ответов

Хорошо, я нашел что-то, что работает. При соединении пакетного файла, поскольку не работал предложенный Vladimir, но аргументы удара были ключевыми.

Короткий и сладкий: партнер этой команды: "C:\cygwin\bin\bash.exe" - литий "%1" % *

версия Long, если Вы не знаете как:

  1. В Проводнике, перейдите к Инструментам/Папке Типы Options/File.
  2. у меня уже была запись SH для Сценария Bash. Если Вы не имеете один, нажмите New и введите "SH" для создания того.
  3. С выбранным расширением SH, нажмите Advanced.
  4. Выбирают "открытое" действие и нажимают редактирование (или создают действие).
  5. Это - команда для использования: "C:\cygwin\bin\bash.exe" - литий "%1" % * . Обратите внимание, что без - литий , это был returing "команда, не найденная" на моих сценариях.

можно также хотеть добавить SH к Вашему переменная среды PATHEXT :

WinKey+Pause / Усовершенствованный / Переменные среды / Системные переменные / PATHEXT

спасибо за Вашу справку, парней!

41
ответ дан Asciiom 26 November 2019 в 18:57
поделиться

Вот мое решение. Это работает хорошо на мои *.sh сценарии независимо от того, где они находятся в иерархии каталогов. Заметьте что я CD к cygpath dirname перед называнием удара на cygpath. Это просто работает.

assoc .sh=bashscript

ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%1")")"; bash "$(cygpath -u "%1")"'
15
ответ дан Jon Ericson 26 November 2019 в 18:57
поделиться

Это не связывает .sh файлы, но это могло бы получить Вас, что Вы хотите. Я запустил с пакетного файла cygwin.bat, который запускает оболочку удара Cygwin и изменил ее как так:

$ cat test.bat
@echo off

set MYDIR=C:\scripts

C:\cygwin\bin\bash --login -c "cd $MYDIR && echo 'Now in' `pwd`; sleep 15"

Это - игрушечный сценарий, но Вы могли изменить его, чтобы назвать rsync или назвать отдельный сценарий оболочки. Я признаю, что было бы более хорошо, если бы это не имело MYDIR трудно кодированным. Существует проребенок, путь действительно заставляет его автоволшебно устанавливать это.

, О, да, когда я создал .bat файл в оболочке удара в Cygwin, я заметил, что имел к на самом деле "chmod +x test.bat", прежде чем я мог запустить его двойным щелчком. Я думаю, что это - полномочия установки NTFS. Вы не должны были бы делать этого, если бы Вы просто использовали блокнот.

2
ответ дан David 26 November 2019 в 18:57
поделиться

Одно решение, которое работы должны создать .bat файл, который откроет cygwin и выполнит Ваш сценарий.

сценарий для выполнения сценария go.sh, расположенного на моем корневом каталоге:

@echo off

C:
chdir C:\cygwin\bin

bash --login -i ./go.sh
0
ответ дан Vladimir 26 November 2019 в 18:57
поделиться

Посмотрите на помощника и команды ftype в поле DOS. Вот пример для .jpg на моей машине

c:\>assoc .jpg
.jpg=jpegfile

c:\>ftype jpegfile
jpegfile="C:\Program Files\Common Files\Microsoft Shared\PhotoEd\PHOTOED.EXE" "%1"

assoc .sh=bashscript

ftype bashscript="c:\cygwin\bin\bash.exe" "%1"

, Удостоверяются, что Вы изменяете путь для избиения ftype команда для соответствия, где Вы имеете cygwin , установил

0
ответ дан AP. 26 November 2019 в 18:57
поделиться

Необходимо смочь связать .sh файлы с \CYGWIN\usr\bin\bash.exe. Сценарий должен будет изменить свой собственный рабочий каталог, я предлагаю засунуть что-то вроде этого наверху:

cd `dirname "$0"`
1
ответ дан Sparr 26 November 2019 в 18:57
поделиться

Вы выбрали глупость проблемы, с которой нужно начать. Такая оптимизация планирования завершена. Существует куча документов о том, как бороться с такими проблемами, как этот класс проблем известен как ограничение удовлетворенности. Вы можете выполнить исчерпывающий поиск, который является самым простым, но также очень трудоемким, если у вас есть более чем несколько классов он не будет работать. Вы можете взглянуть на основу решателя, который является номером люкс инструментов для .net для решения этих видов вещей. Скотт Хансельман сделал подкаст об этом здесь http://www.hanselminutes.com/default.aspx?showID=209 и вы можете узнать больше об этом здесь http://code.msdn.microsoft.com/solverfoundation . Если вы хотите сделать это сами попробуйте посмотреть на GSAT или иначе некоторые из этих эволюционных алгоритмов выглядят интересно http://www.springer.com/engineering/book/978-3-540-48582-7 .

-121--4950377-

Это может быть связано с тем, что вы не располагаете своим WebResponse или StreamReaders:

var request = WebRequest.Create(...);
using (var response = request.GetResponse())
{
    using (var responseStream = response.GetResponseStream())
    {
        using (var reader = new StreamReader(responseStream))
        {
            // use the reader
        }
    }
}
-121--3147264-

Я просто не беспокоился. Я ассоциировал файлы .sh с Crimson Editor (так как я трачу столько времени на отработку ошибок, сколько на самом деле их запускаю). Теперь необходимо получить правильную комбинацию «открыть с/изменить с» для работы в меню «Типы файлов» > «Дополнительно». Если бы я знал, какой код DDE использовал Crimson Editor, это облегчило бы ситуацию; на этом посту я не смог найти его, однако.

Это напоминает мне мои дни Mac (1993-2008), когда я пытался отсканировать приложения для более чем элементарной скриптабельности, чем элементарная.

BZT

0
ответ дан 26 November 2019 в 18:57
поделиться

Я использую PuttyCyg (удивительный putty в окне Cygwin), вот как все это запустить:

Создайте пакетный скрипт, например, на моей машине я использовал

C:\Dev\scripts\cygbashrun.bat

с содержимым

SET CYGWIN=nodosfilewarning
C:\Cygwin\bin\putty.exe -cygterm /bin/bash.exe %1

Очевидно, адаптируйте, чтобы содержать пути вашей установки PuttyCyg.

Затем в Windows File Explorer перейдите в Tools - Folder Options - File Types

Создайте запись ".sh", если ее еще нет (или .bash, в зависимости от того, что вам нравится в ваших скриптах)... затем Advanced...

[необязательный шаг] измените значок и выберите значок Cygwin из вашей установки

Затем:

  1. Новый...
  2. Действие = Запустить Bashscript...
  3. Приложение, используемое для выполнения этого действия = C:\Dev\scripts\cygbashrun.bat "%1"

Работает как шарм для меня :O)

0
ответ дан 26 November 2019 в 18:57
поделиться

Я уже некоторое время работаю с решением Dragos и считаю его лучшим, поскольку оно устраняет необходимость использования "cygpath -u" в сценариях оболочки.

Затем я захотел иметь дополнительные функции, такие как поддержка перетаскивания файлов .sh и .bash. Покопавшись, я написал .bat, который связывает файлы .sh и .bash как «bashscript» и активирует для них обработчик перетаскивания Windows Explorer. Мне пришлось отредактировать команду Dragos, чтобы она обрабатывала 1 аргумент (путь к элементу, помещенному в сценарий оболочки).

Файл .bat выглядит примерно следующим образом:

echo Registering .sh and .bash files as "bashscript"...
assoc .sh=bashscript
assoc .bash=bashscript
echo.
echo Setting the run command for the file type "bashscript"...
ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%%1")")"; bash "$(cygpath -u "%%1")" "$(/argshandler.sh "%%2")"'
echo.
echo Activating the drag^&drop capability for "bashscript" files (only 1 dropped item
echo will be passed to the script, multiple items are not supported yet)...
reg add HKEY_CLASSES_ROOT\bashscript\shellex\DropHandler /v "" /t REG_SZ /d "{60254CA5-953B-11CF-8C96-00AA00B8708C}" /f

Сценарий "argshandler.sh" в корне Cygwin просто возвращает первый аргумент, который он получает, и ничего не делает, если его нет (например, если вы просто удвоили щелкните файл сценария):

#!/bin/bash
if [ ! "$1" == "" ]
then
    cygpath -u "$1"
fi

Пока все это работает довольно хорошо. Тем не менее, все еще есть некоторые недостатки, которые было бы неплохо устранить:

  • Команда Dragos и моя производная от нее не работают, когда дело доходит до скриптов, расположенных на UNC-путях, например \\ myserver \ myshare \ scriptfile.sh
  • Только 1 отброшенный элемент будет передан в сценарий оболочки.

Каким-то образом, что касается проблемы с одним выпадающим элементом, изменение сценария обработчика аргументов, чтобы вернуть что-то вроде

"cygpathed-arg1" "cygpathed-arg2" "cygpathed-arg3"

, и изменение установщика команды Dragos на что-то вроде

...; bash "$(cygpath -u "%%1")" $(/argshandler.sh "%%2" "%%3" ... "%%9")'

(обратите внимание, что "" вокруг часть argshandler.sh отсутствует), похоже, не работает должным образом: если некоторые из элементов, перетаскиваемых в скрипт, содержат пробел в своем пути, указанные пути будут разбиты на несколько аргументов в пробелах, даже если каждый из них заключен в двойных кавычках ... странно.

Есть ли специалисты по командной строке, которые готовы решить одну или обе эти проблемы?

6
ответ дан 26 November 2019 в 18:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: