One place for hosting & domains

      sistema

      Como usar o módulo pathlib para manipular os caminhos de sistema de arquivos no Python 3


      O autor selecionou a COVID-19 Relief Fund​​​​​ para receber uma doação como parte do programa Write for DOnations.

      Introdução

      O Python 3 inclui o módulo pathlib para manipular caminhos de sistema de arquivos de maneira independente, seja qual for o sistema operacional. O pathlib é semelhante ao módulo os.path, mas o pathlib oferece um nível mais elevado — e muitas vezes mais conveniente — de interface do que o os.path.

      Podemos identificar arquivos em um computador com caminhos hierárquicos. Por exemplo, podemos identificar o arquivo wave.txt em um computador com este caminho: /Users/sammy/ocean/wave.txt. Os sistemas operacionais representam caminhos de maneira ligeiramente diferente. O Windows pode representar o caminho para o arquivo wave.txt como C:Userssammyoceanwave.txt.

      O módulo pathlib pode ser útil para você se em seu programa Python você estiver criando ou movendo arquivos no sistema de arquivos, listando arquivos no sistema de arquivos em que todos correspondam a uma dada extensão ou padrão, ou criando caminhos de arquivo apropriados ao sistema operacional baseados em coleções de strings brutas. Embora seja possível usar outras ferramentas (como o módulo os.path) para realizar muitas dessas tarefas, o módulo pathlib permite que você execute essas operações com um alto grau de legibilidade e uma quantidade mínima de código.

      Neste tutorial, vamos revisar algumas das maneiras de usar o módulo pathlib para representar e manipular os caminhos de sistema de arquivos.

      Pré-requisitos

      Para tirar o máximo proveito deste tutorial, é recomendado ter alguma familiaridade com programação em Python 3. Você pode revisar esses tutoriais para as informações básicas necessárias:

      Construindo instâncias Path

      O módulo pathlib oferece várias classes, mas uma das mais importantes é a classe Path. As instâncias da classe Path representam um caminho para um arquivo ou diretório no sistema de arquivos do nosso computador.

      Por exemplo, o código a seguir cria uma instância Path que representa parte do caminho para um arquivo wave.txt:

      from pathlib import Path
      
      wave = Path("ocean", "wave.txt")
      print(wave)
      

      Se executarmos esse código, receberemos um resultado como o seguinte:

      Output

      ocean/wave.txt

      from pathlib import Path torna a classe Path disponível para nosso programa. Em seguida, Path("ocean", "wave.txt") cria uma nova instância do Path. Imprimir o resultado mostra que o Python adicionou o separador de sistema operacional / apropriado entre os dois componentes do caminho que demos a ele: "ocean" e "wave.txt".

      Nota: dependendo do seu sistema operacional, o resultado pode variar ligeiramente dos resultados de exemplo exibidos neste tutorial. Se estiver utilizando o Windows, por exemplo, seu resultado para este primeiro exemplo se pareceria com oceanwave.txt.

      Agora, o objeto Path atribuído à variável wave contém um caminho relativo. Em outras palavras, ocean/wave.txt pode existir em vários lugares em nosso sistema de arquivos. Para exemplificar, ele pode existir em /Users/user_1/ocean/wave.txt ou /Users/user_2/research/ocean/wave.txt, mas não especificamos exatamente a qual deles estamos nos referindo. Um caminho absoluto, por outro lado, refere-se sem sombra de dúvidas a uma localização específica no sistema de arquivos.

      Use o Path.home() para obter o caminho absoluto para o diretório home do usuário atual:

      home = Path.home()
      wave_absolute = Path(home, "ocean", "wave.txt")
      print(home)
      print(wave_absolute)
      

      Se executarmos esse código, receberemos um resultado parecido com o seguinte:

      Output

      /Users/sammy /Users/sammy/ocean/wave.txt

      Nota: como mencionado anteriormente, seu resultado irá variar dependendo do seu sistema operacional. Seu diretório home, por consequência, também será diferente de /Users/sammy.

      Path.home() retorna uma instância Path com um caminho absoluto para o diretório home do usuário atual. Em seguida, passamos essa instância Path e as strings "ocean" e "wave.txt" para outro construtor Path de forma a criar um caminho absoluto para o arquivo wave.txt. O resultado mostra que a primeira linha é o diretório home, e a segunda linha é o diretório home mais ocean/wave.txt.

      Este exemplo também ilustra uma característica importante da classe Path: o construtor Path aceita tanto strings quanto objetos Path pré-existentes.

      Vamos analisar as strings e objetos Path no construtor Path um pouco mais de perto:

      shark = Path(Path.home(), "ocean", "animals", Path("fish", "shark.txt"))
      print(shark)
      

      Se executarmos esse código Python, receberemos um resultado semelhante ao seguinte:

      Output

      /Users/sammy/ocean/animals/fish/shark.txt

      shark é um Path para um arquivo que construímos usando dois objetos Path (Path.home() e Path("fish", "shark.txt")) e as strings ("ocean" e "animals"). O construtor Path lida com os dois tipos de objetos de maneira inteligente e une-os corretamente usando o separador de sistema operacional adequado, neste caso, /.

      Acessando os atributos de arquivo

      Agora que aprendemos como construir instâncias Path, vamos analisar como você pode usar essas instâncias para acessar informações sobre um arquivo.

      Podemos usar os atributos name e suffix para acessar os nomes e sufixos dos arquivos:

      wave = Path("ocean", "wave.txt")
      print(wave)
      print(wave.name)
      print(wave.suffix)
      

      Ao executar este código, receberemos um resultado semelhante ao seguinte:

      Output

      /Users/sammy/ocean/wave.txt wave.txt .txt

      Este resultado mostra que o nome do arquivo no final do nosso caminho é wave.txt e o sufixo desse arquivo é .txt.

      As instâncias Path também oferecem a função with_name que permite criar rapidamente um novo objeto Path com um nome diferente:

      wave = Path("ocean", "wave.txt")
      tides = wave.with_name("tides.txt")
      print(wave)
      print(tides)
      

      Se executarmos o código acima, receberemos um resultado como o seguinte:

      ocean/wave.txt
      ocean/tides.txt
      

      Primeiro, o código constrói uma instância Path que aponta para um arquivo chamado wave.txt. Em seguida, chamamos o método with_name em wave para retornar uma segunda instância Path que aponta para um novo arquivo chamado tides.txt. A porção de diretório ocean/ do caminho permanece inalterada, deixando o caminho final como sendo ocean/tides.txt

      Acessando diretórios ancestrais

      Às vezes, é útil acessar diretórios que contêm um dado caminho. Vamos considerar um exemplo:

      shark = Path("ocean", "animals", "fish", "shark.txt")
      print(shark)
      print(shark.parent)
      

      Se executarmos esse código, receberemos um resultado parecido com o seguinte:

      Output

      ocean/animals/fish/shark.txt ocean/animals/fish

      O atributo parent em uma instância Path retorna o ancestral mais próximo de um determinado caminho de arquivo. Neste caso, ele retorna o diretório que contém o arquivo shark.txt: ocean/animals/fish.

      Podemos acessar o atributo parent várias vezes seguidas para percorrer a árvore de ancestralidade de um dado arquivo:

      shark = Path("ocean", "animals", "fish", "shark.txt")
      print(shark)
      print(shark.parent.parent)
      

      Se executarmos esse código, receberemos o seguinte resultado:

      Output

      ocean/animals/fish/shark.txt ocean/animals

      O resultado é semelhante ao resultado anterior, mas agora percorremos mais um nível acessando .parent uma segunda vez. Dois diretórios acima de shark.txt, você encontrará o diretório ocean/animals.

      Usando Glob para listar arquivos

      Também é possível usar a classe Path para listar arquivos usando o método glob.

      Suponha que tivéssemos uma estrutura de diretório que se parecia com esta:

      └── ocean
          ├── animals
          │   └── fish
          │       └── shark.txt
          ├── tides.txt
          └── wave.txt
      

      Um diretório ocean contém os arquivos tides.txt e wave.txt. Temos um arquivo chamado shark.txt contido no diretório ocean, um diretório animals e um diretório fish: ocean/animals/fish.

      Para listar todos os arquivos .txt no diretório ocean, podemos utilizar:

      for txt_path in Path("ocean").glob("*.txt"):
          print(txt_path)
      

      Esse código produziria um resultado como este:

      Output

      ocean/wave.txt ocean/tides.txt

      O padrão glob "*.txt" encontra todos os arquivos terminados em .txt. Como a amostra de código executa esse glob no diretório ocean, ela retorna os dois arquivos .txt no diretório ocean: wave.txt e tides.txt.

      Nota: se você quiser replicar os resultados mostrados neste exemplo, você precisará imitar a estrutura de diretórios aqui ilustrada em seu computador.

      Também podemos usar o método glob recursivamente. Para listar todos os arquivos .txt no diretório ocean e todos os seus subdiretórios, podemos utilizar:

      for txt_path in Path("ocean").glob("**/*.txt"):
          print(txt_path)
      

      Se executarmos esse código, receberemos um resultado como o seguinte:

      Output

      ocean/wave.txt ocean/tides.txt ocean/animals/fish/shark.txt

      A parte ** do padrão glob irá corresponder a esse diretório e todos os diretórios abaixo dele, recursivamente. Dessa forma, não só temos os arquivos wave.txt e tides.txt no resultado, mas também recebemos o arquivo shark.txt que estava contido em ocean/animals/fish.

      Computando caminhos relativos

      Podemos usar o método Path.relative_to para computar caminhos em relação uns aos outros. O método relative_to é útil quando, por exemplo, você quiser recuperar parte de um caminho de arquivo longo.

      Considere o código a seguir:

      shark = Path("ocean", "animals", "fish", "shark.txt")
      below_ocean = shark.relative_to(Path("ocean"))
      below_animals = shark.relative_to(Path("ocean", "animals"))
      print(shark)
      print(below_ocean)
      print(below_animals)
      

      Se executarmos o código acima, receberemos um resultado como o seguinte:

      Output

      ocean/animals/fish/shark.txt animals/fish/shark.txt fish/shark.txt

      O método relative_to retorna um novo objeto Path relativo ao argumento dado. Em nosso exemplo, computamos o Path para o shark.txt relativo ao diretório ocean, e então relativo tanto ao diretório ocean quanto ao diretório animals.

      Se relative_to não puder computar uma resposta porque lhe fornecemos um caminho não relacionado, ele gera um ValueError:

      shark = Path("ocean", "animals", "fish", "shark.txt")
      shark.relative_to(Path("unrelated", "path"))
      

      Receberemos uma exceção ValueError gerada a partir deste código que será algo parecido com isto:

      Output

      Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/Python3.8/pathlib.py", line 899, in relative_to raise ValueError("{!r} does not start with {!r}" ValueError: 'ocean/animals/fish/shark.txt' does not start with 'unrelated/path'

      unrelated/path não faz parte de ocean/animals/fish/shark.txt, então não existe nenhuma maneira para o Python computar um caminho relativo.

      Conclusão

      O módulo pathlib é uma parte poderosa da Biblioteca Padrão do Python que nos permite manipular caminhos do sistema de arquivos rapidamente em qualquer sistema operacional. Neste tutorial, aprendemos a usar alguns utilitários chave do pathlib para acessar atributos de arquivo, listar arquivos com padrões glob e percorrer arquivos e diretórios pais.

      O módulo pathlib também oferece classes e utilitários adicionais que não abordamos neste tutorial. Agora que você tem um conhecimento base, use a documentação do módulo pathlib para aprender mais sobre outras classes e utilitários disponíveis.

      Se estiver interessado em usar outras bibliotecas do Python, confira os seguintes tutoriais:



      Source link

      Configuración inicial del servidor con el sistema Ubuntu 18.04


      Introducción

      Para crear un nuevo servidor Ubuntu 18.04, debe seguir algunos pasos iniciales como parte de la configuración básica. Esto aumentará la seguridad y la facilidad de uso del servidor y constituirá una base sólida para acciones posteriores.

      Nota: la siguiente guía muestra cómo completar manualmente los pasos que recomendamos para los nuevos servidores Ubuntu 18.04. Seguir este procedimiento en forma manual puede ser útil para adquirir algunas habilidades básicas de administración del sistema y como un ejercicio para comprender acabadamente las acciones que se realizan en el servidor. Como alternativa, si desea comenzar a trabajar más rápidamente, puede ejecutar nuestro script de configuración inicial del servidor que automatiza estos pasos.

      Paso 1 — Iniciar sesión como usuario «raíz»

      Para iniciar sesión en el servidor, deberá conocer su «dirección IP pública del servidor». También necesitará la contraseña o, si instaló una clave SSH para la autenticación, la clave privada para la cuenta del usuario «raíz». Si aún no ha iniciado sesión en su servidor, puede seguir nuestra guía sobre cómo conectarse a su Droplet con SSH, que cubre este proceso en detalle.

      Si aún no está conectado a su servidor, avance e inicie sesión como usuario «raíz» con el siguiente comando (sustituya la parte resaltada del comando con la dirección IP pública del servidor):

      Si aparece, acepte la advertencia sobre la autenticidad del host. Si utiliza la autenticación de contraseña, indique su contraseña «raíz» para iniciar sesión. Si tiene una clave SSH que está protegida con una frase de contraseña, es posible que se le solicite ingresar la frase de contraseña la primera vez que use la clave en cada sesión. Si es la primera vez que inicia sesión en el servidor con una contraseña, es posible que también se le solicite que cambie la contraseña «raíz».

      Acerca del usuario «raíz»

      El usuario «raíz» es el usuario administrativo en un entorno Linux que tiene privilegios muy amplios. Debido a los mayores privilegios de la cuenta «raíz», se recomienda no utilizarla regularmente. Esto se debe a que parte del poder inherente de la cuenta «raíz» es la capacidad de realizar cambios que podrían resultar muy destructivos, incluso en forma accidental.

      El siguiente paso es configurar una cuenta de usuario alternativa con un alcance reducido para el trabajo cotidiano. Le enseñaremos cómo obtener mayores privilegios en los momentos en que los necesite.

      Paso 2 — Crear un nuevo usuario

      Una vez que haya iniciado sesión como «raíz», estará preparado para agregar la nueva cuenta de usuario que usará para iniciar sesión de ahora en adelante.

      Este ejemplo crea un nuevo usuario llamado «sammy», pero debe reemplazarlo con el nombre de usuario de su preferencia:

      Se le harán algunas preguntas, comenzando con la contraseña de la cuenta.

      Ingrese una contraseña segura y, opcionalmente, complete cualquier información adicional si lo desea. Esto no es obligatorio y puede presionar «INTRO» en cualquier campo que desee omitir.

      Paso 3 — Concesión de privilegios administrativos

      Ahora, tenemos una nueva cuenta de usuario con los privilegios de una cuenta regular. Sin embargo, a veces necesitamos realizar tareas administrativas.

      Para evitar tener que cerrar la sesión del nuestro usuario regular y volver a iniciar sesión con la cuenta «raíz», podemos configurar lo que se conoce como privilegios de «superusuario» o «raíz» para nuestra cuenta regular. Esto permitirá a nuestro usuario regular ejecutar comandos con privilegios administrativos poniendo la palabra «sudo» antes de cada comando.

      Para agregar estos privilegios a nuestro nuevo usuario, necesitamos agregar el nuevo usuario al grupo «sudo». De forma predeterminada, Ubuntu 18.04 permite que los usuarios que pertenecen al grupo «sudo» usen el comando «sudo».

      Desde la cuenta «raíz», ejecute este comando para agregar su nuevo usuario al grupo «sudo» (sustituya la palabra resaltada con su nuevo usuario):

      Ahora, cuando inicie sesión como su usuario regular, puede escribir «sudo» antes de los comandos para realizar acciones con privilegios de superusuario.

      Paso 4 — Configuración de un cortafuegos básico

      Los servidores Ubuntu 18.04 pueden usar el cortafuegos UFW para asegurarse de que solo se permitan conexiones a ciertos servicios. Podemos configurar un cortafuegos básico muy fácilmente con esta aplicación.

      Nota: si sus servidores se ejecutan en DigitalOcean, puede usar opcionalmente DigitalOcean Cloud Firewalls en lugar del cortafuegos UFW. Recomendamos utilizar solo un cortafuegos a la vez para evitar reglas conflictivas que sean difíciles de depurar.

      Las diferentes aplicaciones pueden registrar sus perfiles en UFW después de la instalación. Estos perfiles permiten a UFW administrar estas aplicaciones por nombre. OpenSSH, el servicio que nos permite conectarnos a nuestro servidor ahora, tiene un perfil registrado en UFW.

      Puede verlo si ingresa:

      Output

      Available applications: OpenSSH

      Necesitamos asegurarnos de que el cortafuegos permita conexiones SSH para que podamos volver a iniciar sesión la próxima vez. Podemos permitir estas conexiones si escribimos:

      Seguidamente, podemos habilitar el cortafuegos si escribimos:

      Escriba «y» y presione «INTRO» para avanzar. Puede ver que estas conexiones SSH aún están permitidas si escribe:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)

      Como «el servidor de seguridad está bloqueando actualmente todas las conexiones excepto SSH», si instala y configura servicios adicionales, deberá ajustar la configuración del cortafuegos para permitir la entrada de tráfico aceptable. Puede aprender algunas operaciones comunes de UFW en esta guía.

      Paso 5 — habilitación del acceso externo para su usuario regular

      Ahora que tenemos un usuario regular para el uso cotidiano, debemos asegurarnos de poder ingresar directamente a la cuenta con SSH.

      Nota: hasta que verifique que puede iniciar sesión y usar «sudo» con su nuevo usuario, le recomendamos que permanezca conectado como «raíz». De esta manera, si tiene problemas, puede solucionarlos y hacer los cambios necesarios como «raíz». Si utiliza un Droplet DigitalOcean y tiene problemas con su conexión SSH «raíz», puede iniciar sesión en Droplet utilizando la consola DigitalOcean.

      El proceso para configurar el acceso SSH para su nuevo usuario depende de si la cuenta «raíz» de su servidor utiliza una contraseña o claves SSH para la autenticación.

      Si la cuenta raíz utiliza autenticación de contraseña

      Si inició sesión en su cuenta «raíz» con «una contraseña», la autenticación de la contraseña está habilitada para SSH. Puede incorporar SSH a su nueva cuenta de usuario abriendo una nueva sesión de terminal y usando SSH con su nuevo nombre de usuario:

      Después de ingresar la contraseña de usuario regular, habrá iniciado sesión. Recuerde, si necesita ejecutar un comando con privilegios administrativos, escriba «sudo» antes, de esta manera:

      Se le solicitará su contraseña de usuario regular cuando use «sudo» por primera vez en cada sesión (y periódicamente después).

      Para mejorar la seguridad de su servidor, «recomendamos enfáticamente que configure las claves SSH en lugar de usar la autenticación de contraseña». Siga las indicaciones de nuestra guía sobre configuración de claves SSH en Ubuntu 18.04 para saber cómo configurar la autenticación basada en clave.

      Si la cuenta raíz utiliza autenticación de clave SSH

      Si inició sesión en su cuenta «raíz» utilizando «claves SSH», la autenticación de la contraseña está «deshabilitada» para SSH. Para iniciar sesión correctamente, deberá agregar una copia de su clave pública local al archivo «~/.ssh/authorized_keys» del nuevo usuario.

      Dado que su clave pública ya está en el archivo «~/.ssh/authorized_keys» de la cuenta «raíz», puede copiar ese archivo y la estructura de directorios en nuestra nueva cuenta de usuario de la sesión actual.

      La forma más sencilla de copiar los archivos con la propiedad y los permisos correctos es con el comando «rsync». Esto copiará el directorio «.ssh» del usuario «raíz», conservará los permisos y modificará los propietarios del archivo, todo en un solo comando. Asegúrese de cambiar las partes resaltadas del comando a continuación para que coincidan con el nombre de su usuario regular:

      Nota: el comando «rsync» trata los orígenes y destinos que terminan con una barra diagonal de manera diferente a aquellos sin barra diagonal final. Cuando utilice «rsync» a continuación, asegúrese de que el directorio de origen («~/.ssh») «no» incluya una barra diagonal final (compruebe que no esté utilizando «~/.ssh/»).

      Si accidentalmente agrega una barra diagonal al comando, «rsync» copiará el «contenido» del directorio «~/.ssh» de la cuenta «raíz» en el directorio principal del usuario «sudo» en lugar de copiar toda la estructura del directorio «~/.ssh». Los archivos estarán en la ubicación incorrecta y SSH no podrá encontrarlos ni utilizarlos.

      • rsync --archive --chown=sammy:sammy ~/.ssh /home/sammy

      Ahora, abra una nueva sesión de terminal y use SSH con su nuevo nombre de usuario:

      Debe iniciar sesión en la cuenta de usuario nuevo sin utilizar contraseña. Recuerde, si necesita ejecutar un comando con privilegios administrativos, escriba «sudo» antes, de esta manera:

      Se le solicitará su contraseña de usuario regular cuando use «sudo» por primera vez en cada sesión (y periódicamente después).

      ¿Dónde ir a partir de aquí?

      En este punto, tiene una base sólida para su servidor. Ahora, puede instalar en él cualquier software que necesite.



      Source link