Apuntes Informatica Documentation Publicación 1.0.0 Salvador Nicolas<snicoper@gmail.com> 17 de November de 2016 Índice general 1. Editores 1.1. Atom . . . . . . . 1.2. Pycharm . . . . . 1.3. Sublime Text . . . 1.4. vim . . . . . . . . 1.5. Visual Studio Code 2. Git 2.1. 2.2. 2.3. 2.4. 2.5. 2.6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 4 8 12 Añadir a gitignore algunos arhivos y quitar otros dentro del mismo directorio. Comandos Basicos Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Git Config Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Git en Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hacer diff y merge con remote . . . . . . . . . . . . . . . . . . . . . . . . . Unstage file or directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 13 13 15 16 18 18 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 . 19 . 22 . 41 . 42 . 43 . 58 . 65 . 67 . 72 . 72 . 73 . 84 . 85 . 87 . 88 . 88 . 88 . 89 . 89 . 91 . 91 . 100 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3. Linux 3.1. Apache . . . . . . . . . . . . . . . . . 3.2. Fedora Centos . . . . . . . . . . . . . 3.3. MariaDB . . . . . . . . . . . . . . . . 3.4. MySQL . . . . . . . . . . . . . . . . . 3.5. Nginx . . . . . . . . . . . . . . . . . . 3.6. PHP . . . . . . . . . . . . . . . . . . . 3.7. PostgreSQL . . . . . . . . . . . . . . . 3.8. Python . . . . . . . . . . . . . . . . . 3.9. Redis . . . . . . . . . . . . . . . . . . 3.10. Ruby . . . . . . . . . . . . . . . . . . 3.11. Ubuntu . . . . . . . . . . . . . . . . . 3.12. Añadir carpetas al PATH . . . . . . . . 3.13. Añadir programas al menu . . . . . . . 3.14. Comando Cat con texto coloreado . . . 3.15. Chromium español linux . . . . . . . . 3.16. Comando dd . . . . . . . . . . . . . . 3.17. Comando find . . . . . . . . . . . . . 3.18. Comando setfacl . . . . . . . . . . . . 3.19. Comprimir descomprimir desde consola 3.20. Configurar mutt . . . . . . . . . . . . 3.21. Comandos Utiles . . . . . . . . . . . . 3.22. Contar lineas de un proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I 3.23. 3.24. 3.25. 3.26. 3.27. 3.28. 3.29. 3.30. 3.31. 3.32. 3.33. 3.34. 3.35. 3.36. 3.37. 3.38. 3.39. 3.40. 3.41. 3.42. 3.43. 3.44. 3.45. 3.46. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 101 102 102 103 103 104 104 105 105 106 106 107 108 110 110 111 112 112 112 112 113 113 113 4. Programacion 4.1. Apuntes sin clasificar . . . . . . . . . . . . . 4.2. C# . . . . . . . . . . . . . . . . . . . . . . 4.3. MariaDB . . . . . . . . . . . . . . . . . . . 4.4. PCRE - Perl Compatible Regular Expressions 4.5. PostgreSQL . . . . . . . . . . . . . . . . . . 4.6. Python . . . . . . . . . . . . . . . . . . . . 4.7. UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 115 118 138 141 143 147 181 5. Windows 5.1. Compartir directorios en VirtualBox . 5.2. Eliminar un Servicio . . . . . . . . . 5.3. Nginx y PHP en Windows . . . . . . 5.4. Instalación de PostgreSQL Windows 5.5. Instalación Python en Windows . . . 5.6. Instalar Cygwin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 185 187 187 190 191 192 II Crear grupos y añadir usuarios a grupos Diferencias entre adduser y useradd . . Instalar Dropbox . . . . . . . . . . . . Formatear discos con mkfs . . . . . . . Generar clave para SSH . . . . . . . . Iconos Numix . . . . . . . . . . . . . Instalacion Discord . . . . . . . . . . . Instalación de Memcached . . . . . . . Instalación MongoDb . . . . . . . . . Instalación NodeJS . . . . . . . . . . . Instalar Golang . . . . . . . . . . . . . Instalar Libsass y SassC . . . . . . . . Instalar Mono Monodevelop Xsp . . . Mostrar Imagenes BIN, ISO, CUE, etc. Montar partición SSH al iniciar sistema Montar particiones al iniciar sistema . . Redimensionar una imagen . . . . . . Saber donde esta un “ejecutable” . . . Saber temperatura del PC . . . . . . . Source Code Pro . . . . . . . . . . . . Tip, crear varios documentos con touch Tunel SSH . . . . . . . . . . . . . . . Ver permisos en octal de los archivos . Virtualbox, problema con Alt Gr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Apuntes Informatica Documentation, Publicación 1.0.0 Contents: Índice general 1 Apuntes Informatica Documentation, Publicación 1.0.0 2 Índice general CAPÍTULO 1 Editores Actualmente en editores de código uso Sublime Text 3, Atom y a ratos pruebo Visual Studio Code Por defecto uso Atom pero para auto corrección del texto, prefiero Sublime Text que de lejos es el mas cómodo. Con Atom, también es posible, pero es bastante mas engorroso. Para debug, vscode parece ser la mejor opción. Actualmente uso el editor para la Web, el frontend lo típico y el backend con Python/Django. Vim lo utilizo para configuraciones del sistema, para código no termino de acostumbrarme a moverme entre archivos y el copy/paste. Pycharm, aunque creo que es lo mejor, sigo prefiriendo algo mas simple. Contents: 1.1 Atom Contents: 1.1.1 Configuración Atom Algunos tips Spell-Check español Primero hacer un backup, de los diccionarios que vienen por defecto (ingles). cd /usr/share/atom/resources/app.asar.unpacked/node_modules/spell-check/node_modules/spellchecker/ven sudo cp en_US.aff en_US.aff.back sudo cp en_US.dic en_US.dic.back Descargar diccionarios desde GitHub y moverlos. cd ~/Downloads git clone git://github.com/SublimeText/Dictionaries.git Dictionaries cd Dictionaries sudo cp Spanish.aff /usr/share/atom/resources/app.asar.unpacked/node_modules/spell-check/node_modules sudo cp Spanish.dic /usr/share/atom/resources/app.asar.unpacked/node_modules/spell-check/node_modules 3 Apuntes Informatica Documentation, Publicación 1.0.0 Edit -> Preferences -> Packages -> Spell Check En Grammars añadir la lista de lenguajes. Para conocer el grammar de un lenguaje pulsar Ctrl+Shift+Alt+P o Ctrl+Shift+P y escribir Editor: Log Cursor Scope. 1.2 Pycharm Contents: 1.2.1 Spell check spanish En GitHub el repo de EOM Poner spanish-utf8.dic en cualquier directorio y desde PyCharm settings > Editor > Spelling y en la pestaña de Dictionaries, añadir el directorio donde se haya puesto el archivo spanish-utf8.dic. 1.3 Sublime Text Contents: 1.3.1 Sublime Text 3 ..warning DEPRECATED, ya no lo uso y dejo de actualizarlo. Instalacion de Package Control Ctrl+Shift+P: Install Package Control Packages DocBlockr EditorConfig Color Highlighter PlainTasks Git GitGutter Git SideBarGit 4 Capítulo 1. Editores Apuntes Informatica Documentation, Publicación 1.0.0 Sass SCSS Python Anaconda Djaneiro React.js Babel (no) ReactJS (no) Theme OneDark Material Linters SublimeLinter SublimeLinter-rst SublimeLinter-json Buscar los nuevos Configuracion Esta configuración la uso tanto en Linux como en Windows, solo mirar que la fuente este instalada o cambiar por otra, también ajustar tamaño fuente. El ‘"theme"‘ y/o el ‘"color_scheme"‘, pueden variar también. Abrir Preferences > Setting - User { // Colors and theme "color_scheme": "Packages/User/SublimeLinter/OneDark (SL).tmTheme", "theme": "OneDarkMaterial.sublime-theme", // Theme Material Theme "material_theme_accent_purple" "always_show_minimap_viewport" "bold_folder_labels" "font_options" "indent_guide_options" "line_padding_bottom" "line_padding_top" "overlay_scroll_bars" : : : : : : : : true , true, true, [ "gray_antialias", "subpixel_antialias" ], // On retina Mac [ "draw_normal", "draw_active" ], // Highlight active indent 3, 3, "enabled", // Font 1.3. Sublime Text 5 Apuntes Informatica Documentation, Publicación 1.0.0 "font_face": "DejaVu Sans Mono", // Editor view look-and-feel "highlight_line": true, "show_minimap": false, "caret_extra_width": 2, "show_encoding": true, "show_line_endings": true, "bold_folder_labels": true, // Editor behavior "highlight_modified_tabs": true, "find_selected_text": true, "shift_tab_unindent" : false, "tab_completion": false, "vintage_start_in_command_mode": true, // Word wrapping - follow PEP 8 recommendations "rulers": [ 100 ], "word_wrap": false, // Whitespace - no tabs, trimming, end files with \n "tab_size": 4, "translate_tabs_to_spaces": true, "trim_trailing_white_space_on_save": true, "ensure_newline_at_eof_on_save": true, // Sidebar - exclude distracting files and folders "file_exclude_patterns": [ ".DS_Store", "*.pyc", ".directory" ], "folder_exclude_patterns": [ ".git", ".svn", ".hg", "__pycache__", ".idea" ], "ignored_packages": [ ] } Key bindings Algunas combinaciones de teclas no me funciona por defecto, por lo que tengo configuradas una pocas. Algunas sin modificar si funcionan en Windows, pero para no tener 2 diferentes, uso esta configuración en ambos sistemas. [ // Indetntar codigo { "keys": ["alt+."], "command": "indent" }, 6 Capítulo 1. Editores Apuntes Informatica Documentation, Publicación 1.0.0 // DesIndentar codigo { "keys": ["alt+,"], "command": "unindent" }, // Comentar linea { "keys": ["alt+c"], "command": "toggle_comment", "args": { "block": false } }, // Comentar bloque { "keys": ["alt+b"], "command": "toggle_comment", "args": { "block": true } }, // Join lines { "keys": ["ctrl+j"], "command": "join_lines" }, // Markdown preview { "keys": ["alt+m"], "command": "markdown_preview", "args": {"target": "browser", "parser":"markd // Word wrap { "keys": ["alt+w"], "command": "toggle_setting", "args": {"setting": "word_wrap"} }, // Reformat code { "keys": ["alt+r"], "command": "reindent" , "args": { "single_line": false } } ] SublimeLinter Preferences -> Package Settings -> SublimeLinter -> Settings - User NOTA: Si el archivo esta vacío, Ctrl+S, cerrar y volver a abrir. # Añadir dentro de "user": { "user": { "lint_mode": "load/save" } Anaconda Fuentes https://github.com/DamnWidget/anaconda/blob/master/Anaconda.sublime-settings La configuración se pone en Preferences -> Package Settings -> Anaconda -> Settings User. Por defecto tengo un virtualenv, para proyectos poner la configuracion a nivel de proyecto o cambiar el python_interpreter { "python_interpreter": "/home/snicoper/.virtualenvs/default/bin/python", "anaconda_linter_mark_style": "none", "complete_parameters": false, "anaconda_gutter_theme": "alpha", "display_signatures": true, "pep8_max_line_length": 100, "auto_formatting": false, "pep8_ignore": 1.3. Sublime Text 7 Apuntes Informatica Documentation, Publicación 1.0.0 [ ], } Poner diccionario castellano Fuentes http://www.snicoper.com/blog/article/poner-diccionario-espanol-en-sublime-text-3/ Linux cd ~/Downloads git clone git://github.com/SublimeText/Dictionaries.git Dictionaries mkdir -p ~/.config/sublime-text-3/Packages/Language cp Dictionaries/Spanish.* ~/.config/sublime-text-3/Packages/Language En ST, en el menú View -> Dictionary, seleccionamos el idioma y luego para resaltar los errores de idioma le damos a F6. Windows Todo igual que en Linux, pero el directorio Language se crea en ~\AppData\Roaming\Sublime Text 3\Packages, dentro poner archivos Dictionaries/Spanish.*. 1.4 vim Contents: 1.4.1 Mi .vimrc vim ~/.vimrc set pastetoggle=<F10> set clipboard=unnamed set encoding=utf8 " Rebind <Leader> key let mapleader = "," " Enable syntax highlighting " You need to reload this file for the change to apply filetype off filetype plugin indent on syntax on set scrolloff=8 8 Capítulo 1. Editores Apuntes Informatica Documentation, Publicación 1.0.0 " Showing line length set nonu set tw=79 " width of document (used by gd) set nowrap " don't automatically wrap on load set fo-=t " don't automatically wrap text when typing set colorcolumn=100 highlight ColorColumn ctermbg=233 " color let g:molokai_original = 1 colo molokai " Useful settings set history=700 "set undolevels=700 set foldlevel=99 " Real programmers don't use TABs but spaces set tabstop=4 set softtabstop=4 set shiftwidth=4 set shiftround set expandtab " Make search case insensitive set hlsearch set incsearch set ignorecase set smartcase " Disable stupid backup and swap files - they trigger too many events " for file system watchers set nobackup set nowritebackup set noswapfile " Split navigations nnoremap <C-J> <C-W><C-J> nnoremap <C-K> <C-W><C-K> nnoremap <C-L> <C-W><C-L> nnoremap <C-H> <C-W><C-H> " Stupid command! command! command! command! command! command! command! command! command! shift -bang -bang -bang -bang -bang -bang -bang -bang -bang key fixes -nargs=* -complete=file -nargs=* -complete=file -nargs=* -complete=file -nargs=* -complete=file Wa wa<bang> WA wa<bang> Q q<bang> QA qa<bang> Qa qa<bang> E e<bang> <args> W w<bang> <args> Wq wq<bang> <args> WQ wq<bang> <args> " Tabs, buffers map <C-n> :bprev<Return> map <C-m> :bnext<Return> map <C-right> :tabn <Return> map <C-left> :tabp <Return> 1.4. vim 9 Apuntes Informatica Documentation, Publicación 1.0.0 " Plug call plug#begin('~/.vim/plugged') Plug Plug Plug Plug Plug Plug Plug Plug Plug Plug Plug Plug Plug Plug Plug 'scrooloose/nerdtree' 'jistr/vim-nerdtree-tabs' 'Xuyuanp/nerdtree-git-plugin' 'klen/python-mode' 'editorconfig/editorconfig-vim' 'ctrlpvim/ctrlp.vim' 'vim-airline/vim-airline' 'tpope/vim-fugitive' 'airblade/vim-gitgutter' 'alvan/vim-closetag' 'jiangmiao/auto-pairs' 'tomasr/molokai' 'Valloric/YouCompleteMe' 'SirVer/ultisnips' 'honza/vim-snippets' call plug#end() " nerdtree map <F5> :NERDTreeToggle<CR> "let g:nerdtree_tabs_open_on_console_startup = 1 " airline set laststatus=2 let g:airline#extensions#tabline#enabled = 1 " YouCompleteMe let g:ycm_python_binary_path = '/home/snicoper/.virtualenvs/default/bin/python' let g:ycm_collect_identifiers_from_tags_files = 1 " Let YCM read tags from Ctags file let g:ycm_use_ultisnips_completer = 1 " Default 1, just ensure let g:ycm_seed_identifiers_with_syntax = 1 " Completion for programming language's keyword let g:ycm_complete_in_comments = 1 " Completion in comments let g:ycm_complete_in_strings = 1 " Completion in string " ultisnips let g:UltiSnipsExpandTrigger = '<C-j>' let g:UltiSnipsJumpForwardTrigger = '<C-j>' let g:UltiSnipsJumpBackwardTrigger = '<C-k>' vim :PlugInstall sudo dnf install automake gcc gcc-c++ kernel-devel cmake python3-devel cd ~/.vim/plugged/YouCompleteMe ./install.sh --clang-completer --system-libclang mkdir -p ~/.vim/colors ln -s ~/.vim/plugged/molokai/colors/molokai.vim ~/.vim/colors/molokai.vim 10 Capítulo 1. Editores Apuntes Informatica Documentation, Publicación 1.0.0 1.4.2 Vim spf13 GitHub spf13 Para el corrector en español, Poner Vim spell en español vim ~/.vimrc.local " { Basicas set mouse= set nofoldenable let g:indent_guides_enable_on_vim_startup = 0 " } " { Syntastic let g:syntastic_check_on_open = 1 let g:syntastic_python_flake8_post_args='--ignore=E501,D100,D101,D102,D105,W391' " } " { Corector español set spell setlocal spell spelllang=es set spellfile=~/.vim/dict_es.add " } vim ~/.vimrc.bundles.local Plugin 'editorconfig/editorconfig-vim' Plugin 'jszakmeister/vim-togglecursor' "Plugin 'mjbrownie/django_completeme' PYTHONPATH vim ~/.bashrc # Añadir export PYTHONPATH="${PYTHONPATH}:/home/snicoper/.virtualenvs/default/lib/python3.5/site-packages" 1.4.3 Poner Vim spell en español Fuentes http://plagatux.es/2008/12/correcion-ortografica-en-vim/ Descargar de aquí los archivos: es.latin1.spl es.latin1.sug 1.4. vim 11 Apuntes Informatica Documentation, Publicación 1.0.0 es.utf-8.spl es.utf-8.sug Imaginando que los archivos están en ~/Downloads/spell/ hay que copiarlos a /usr/share/vim/vim74/spell cd ~/Downloads/spell/ sudo cp ./* /usr/share/vim/vim74/spell/ Ahora editamos el vimrc vim ~/.vimrc # Añadimos set spell setlocal spell spelllang=es Si queremos añadir palabras a nuestro diccionario, en vimrc añadir. set spellfile=~/.vim/dict_es.add ]s – Siguiente falta ortográfica [s – Anterior falta ortográfica z= – Mostrar sugerencias para una palabra incorrecta. zg – Añadir una palabra al diccionario. zug – Deshacer la adición de una palabra al diccionario. zw – Eliminar una palabra del diccionario. 1.5 Visual Studio Code Contents: 1.5.1 Visual Studio Code Algunos tips Task Runner Ctrl+Mayus+P -> Tasks: Configure Task Runner -> Other { // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", "command": "/home/snicoper/.virtualenvs/default/bin/python", "isShellCommand": true, "args": ["${file}"], "showOutput": "always" } Ctrl+Mayus+B para ejecutar archivo. 12 Capítulo 1. Editores CAPÍTULO 2 Git Contents: 2.1 Añadir a gitignore algunos arhivos y quitar otros dentro del mismo directorio. Si se ha añadido a gitignore un directorio, pero si se quiere tackear algun archivo en especifico es posible hacerlo con !. Un ejemplo, se quiere tener control sobre media/profiles/avatar.png, pero en gitignore media esta añadido. # Añade todo el contenido de media media/* # Excepto profiles !media/profiles # Añadir todo el contenido de profiles media/profiles/* # Excepto la imagen que queremos tener control. !media/profiles/avatar.png 2.2 Comandos Basicos Git 2.2.1 Links http://www.maefloresta.com/portal/es/git.es Nota: Es una recopilación que voy encontrando, generalmente son cosas simples. 2.2.2 Comandos Basicos Creacion de un repositorio. 13 Apuntes Informatica Documentation, Publicación 1.0.0 git init . Clonar un repositorio. git clone url Añade un directorio de manera recursiva, o un archivo para que sea incluido en el próximo commit. git add nombre Añade todos los archivos para que sea incluido en el próximo commit. git add --all Eliminar un archivo o directorio de manera recursiva. git rm nombre Mover archivo o directorio a una nueva ruta. # -f : Sobre-escribe los cambios locales no guardados git mv nombre Imprime un reporte del estado actual del árbol de trabajo local. # git st, por el alias git status Muestra la diferencia entre los cambios en el árbol de trabajo local. git diff ruta Muestra las diferencias entre los cambios registrados y los no registrados. git diff HEAD ruta Marca el archivo para que no sea incluido en el próximo commit. git reset HEAD ruta Realiza el commit de los archivos que han sido registrados (con git-add) -a : Automáticamente registra todos los archivos modificados. -m 'Texto del commit aqui' : Añade automaticamente el commit con el comentario. git commit Deshace commit & conserva los cambios en el árbol de trabajo local. git reset --soft HEAD^ Restablece el árbol de trabajo local a la versión del ultimo commit. git reset --hard HEAD^ Elimina archivos desconocidos del árbol de trabajo local. git clean Muestra el log del commit, opcionalmente de la ruta especifica. git log [ruta] 14 Capítulo 2. Git Apuntes Informatica Documentation, Publicación 1.0.0 Trae los cambios desde un repositorio remoto. git fetch [remote] Descarga y guarda los cambios realizados desde un repositorio remoto. git pull [remote] Guarda los cambios en un repositorio remoto. git push [remote] Lista los repositorios remotos. git remote Añade un repositorio remoto a la lista de repositorios registrados. git remote add remote url Cambia el árbol de trabajo local a la rama indicada. # -b rama : Crea la rama antes de cambiar el árbol de trabajo local a dicha rama. git checkout rama Lista las ramas locales. git branch Eliminar un brach. git brach -d brach Sobre-escribe la rama existente y comienza desde la revisión. git branch -f rama rev Guarda los cambios desde la rama. git merge rama untacker files git rm -r --cached <your directory> 2.3 Git Config Linux Nota, ahora al usar los dotfiles estos lo mismo estan obsoletos pero los dejo por Kdiff3 vim ~/.gitconfig 2.3.1 Configuracion con Kdiff3 [user] name = Salvador Nicolas email = snicoper@gmail.com [color] ui = true 2.3. Git Config Linux 15 Apuntes Informatica Documentation, Publicación 1.0.0 [core] editor = vim [alias] lg = log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %an)%Creset' --abbre co = checkout cm = commit st = status br = branch [merge] tool = kdiff3 [diff] tool = kdiff3 [mergetool] prompt = false keepBackup = false trustExitCode = false keepTemporaries = false [push] default = current 2.3.2 Configuración con Meld [user] name = Salvador Nicolas email = snicoper@gmail.com [color] ui = true [core] editor = vim [alias] lg = log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %an)%Creset' --abbre co = checkout cm = commit st = status br = branch [merge] tool = meld [diff] tool = meld [mergetool] prompt = false keepBackup = false trustExitCode = false keepTemporaries = false [push] default = current 2.4 Git en Windows Instalar Git Añadir al path C:\Program Files (x86)\Git\bin;C:\Program Files (x86)\Git\cmd; 16 Capítulo 2. Git Apuntes Informatica Documentation, Publicación 1.0.0 2.4.1 Gitconfig con kdiff3 Descargar Kdiff3 [user] name = Salvador Nicolas email = snicoper@gmail.com [color] ui = true [core] editor = vim [alias] lg = log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %an)%Creset' --abbre co = checkout cm = commit st = status br = branch [merge] tool = kdiff3 [diff] tool = kdiff3 [mergetool "kdiff3"] path = C:/Program Files/KDiff3/kdiff3.exe prompt = false keepBackup = false trustExitCode = false keepTemporaries = false [push] default = simple 2.4.2 Gitconfig con Meld [user] name = Salvador Nicolas email = snicoper@gmail.com [color] ui = true [core] editor = vim [alias] lg = log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %an)%Creset' --abbre co = checkout cm = commit st = status br = branch [merge] tool = meld [diff] tool = meld [mergetool "meld"] path = "C:\\Program Files (x86)\\Meld\\Meld.exe" prompt = false keepBackup = false trustExitCode = false keepTemporaries = false [push] default = simple 2.4. Git en Windows 17 Apuntes Informatica Documentation, Publicación 1.0.0 2.5 Hacer diff y merge con remote Primero hay que obtener las diferencias git fetch origin y ahora ver las diferencias. git difftool origin/master Ahora hay que hacer merge, se puede usar merge o mergetool 2.6 Unstage file or directory Fuentes http://stackoverflow.com/questions/6919121/why-are-there-2-ways-to-unstage-a-file-in-git Para hacer unstaging de un archivo o directorio git rm --cached ruta/file/or/dir git rm --cached se utiliza para eliminar un archivo del índice. En el caso de que el archivo ya está en el repositorio, git rm --cached eliminará el archivo del índice, dejándolo en el directorio de trabajo. 18 Capítulo 2. Git CAPÍTULO 3 Linux Categorias: 3.1 Apache 3.1.1 Instalacion de Apache Fedora dnf -y install httpd Remove test page rm -f /etc/httpd/conf.d/welcome.conf vim /etc/httpd/conf/httpd.conf Opcional # line 86: Admin's address ServerAdmin snicoper@gmail.com # line 95: change to your server's name ServerName www.workspace.local:80 # Añadir en la ultima linea # server's header ServerTokens Prod # ServerSignature ServerSignature Off SELinux Ver Reglas SELinux systemctl start httpd.service systemctl enable httpd.service 19 Apuntes Informatica Documentation, Publicación 1.0.0 Firewall firewall-cmd --permanent --zone=public --add-service=http firewall-cmd --permanent --zone=public --add-service=https firewall-cmd --reload Ubuntu sudo apt-get -y install apache2 3.1.2 Apache Virtualhost Siempre creo los entornos en el ~/usuario/public_html pero se podría poner donde uno quiera. Fedora Como root todo mkdir chmod chmod chown /home/snicoper/public_html 711 /home/snicoper 755 /home/snicoper/public_html snicoper:snicoper /home/snicoper/public_html Ubuntu mkdir /home/snicoper/public_html Crear virtualhost, fedora y ubuntu # Fedora vim /etc/httpd/conf.d/workspace.local.conf # Ubuntu sudo vim /etc/apache2/sites-available/workspace.local <VirtualHost *:80> DocumentRoot /home/snicoper/public_html ServerName www.workspace.local ServerAlias www.workspace.local DirectoryIndex index.php ServerAdmin snicoper@gmail.com ErrorLog /var/log/httpd/workspace.local-error_log CustomLog /var/log/httpd/workspace.local-access_log combined <Directory /home/snicoper/public_html> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all Require all granted </Directory> </VirtualHost> 20 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Ubuntu a2enmod rewrite a2dissite default a2ensite workspace.local SELinux Ver Reglas SELinux SSL Fedora yum install mod_ssl mkdir /etc/httpd/ssl openssl req -new -x509 -days 365 -nodes -out /etc/httpd/ssl/httpd.pem -keyout /etc/httpd/ssl/httpd.ke Country Name (2 letter code) [XX]:es State or Province Name (full name) []:Spain Locality Name (eg, city) [Default City]:Barcelona Organization Name (eg, company) [Default Company Ltd]:snicoper Organizational Unit Name (eg, section) []:personal Common Name (eg, your name or your server's hostname) []:lxmaq1.workspace.local Email Address []:snicoper@gmail.com Ahora es cada virtual host, hacer una copia y modificar cp /etc/httpd/conf.d/workspace.conf /etc/httpd/conf.d/ssl.workspace.conf vim /etc/httpd/conf.d/ssl.workspace.conf <VirtualHost *:443> SSLEngine On SSLCertificateFile /etc/httpd/ssl/httpd.pem SSLCertificateKeyFile /etc/httpd/ssl/httpd.key DocumentRoot /home/snicoper/public_html ServerName www.workspace.local ServerAdmin snicoper@gmail.com ErrorLog /var/log/httpd/workspace.local-error_log CustomLog /var/log/httpd/workspace.local-access_log combined <Directory /home/snicoper/public_html> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all Require all granted </Directory> </VirtualHost> Ubuntu POR HACER 3.1. Apache 21 Apuntes Informatica Documentation, Publicación 1.0.0 3.2 Fedora Centos Contents: 3.2.1 Enviar alertas SELinux por email Fuentes http://major.io/2011/09/15/receive-e-mail-reports-for-selinux-avc-denials/ yum install setroubleshoot{-server,-plugins,-doc} El archivo de configuracion esta en: /etc/setroubleshoot/setroubleshoot.conf, lo dejo todo por defecto. echo "selinux@mycompany.com" >> /var/lib/setroubleshoot/email_alert_recipients service messagebus restart Para probarlo, cambiar el puerto de ssh y conectar. 3.2.2 Bind dnf install -y bind bind-utils echo 'OPTIONS="-4"' >> /etc/sysconfig/named vim /etc/named.conf # Linea 11 listen-on port 53 { 127.0.0.1; 192.168.1.0/24; }; # Linea 17 allow-query { localhost; 192.168.1.0/24; }; Añadir despues de logging { #.... } zone "snicoper.local" { type master; file "snicoper.local"; allow-update { none; }; }; zone "1.168.192.in-addr.arpa" IN { type master; file "reverse.snicoper.local"; allow-update { none; }; }; vim /var/named/snicoper.local 22 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 $TTL 86400 @ IN ; SOA snicoper.local. hostmaster.snicoper.local. ( 2013042201 ; Serial 43200 ; Refresh 3600 ; Retry 3600000 ; Expire 2592000 ) ; Minimum Define the nameservers and the mail servers mail ns1 www IN NS ns1.snicoper.local. IN A 192.168.1.100 IN MX 10 mail.snicoper.local. IN IN IN A A CNAME 192.168.1.100 192.168.1.100 ns1 vim /var/named/reverse.snicoper.local $TTL 86400 @ IN 100 SOA snicoper.local. hostmaster.snicoper.local. ( 2013042201 ; Serial 43200 ; Refresh 3600 ; Retry 3600000 ; Expire 2592000 ) ; Minimum IN NS ns1.snicoper.local. IN PTR ns1.snicoper.local. En /etc/sysconfig/network-scripts/ifcfg-* al menos tener lo siguiente: BOOTPROTO=none PEERDNS=no DOMAIN="snicoper.local" IPADDR=192.168.1.100 NETMASK=255.255.255.0 GATEWAY=192.168.1.1 DNS1=127.0.0.1 DNS2=8.8.8.8 DNS3=8.8.4.4 systemctl restart NetworkManager.service SELinux y firewall Reglas SELinux firewall-cmd --permanent --zone=public --add-service=dns firewall-cmd --reload systemctl start named.service systemctl enable named.service 3.2. Fedora Centos 23 Apuntes Informatica Documentation, Publicación 1.0.0 3.2.3 Cambiar Plymouth yum install plymouth-theme-solar plymouth-set-default-theme solar dracut --force reboot Para saber los themes que tenemos instalados. plymouth-set-default-theme -l 3.2.4 Configurar Red Fuentes http://superuser.com/questions/645487/static-ip-address-with-networkmanager Como administrador e ir a donde están los archivos de red. su cd /etc/sysconfig/network-scripts/ Editar segun la interface que use. vim ifcfg-p2p1 Nota: Cuidado no tocar algunas variables como UUID o HWADDR. TYPE=Ethernet BOOTPROTO=none DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_PEERDNS=yes IPV6_PEERROUTES=yes IPV6_FAILURE_FATAL=no NAME=p2p1 UUID=7622e20e-3f2a-4b5c-83d8-f4f6e22ed7ec ONBOOT=yes HWADDR=00:14:85:BC:1C:63 IPADDR=192.168.1.10 NETMASK=255.255.255.0 GATEWAY=192.168.1.1 DNS1=127.0.0.1 DNS2=8.8.8.8 DNS3=8.8.4.4 3.2.5 Configurar SSH Fuentes 24 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 http://www.snicoper.com/blog/article/configuracion-ssh-en-centos-7/ — Configuración basica de SSH dnf install ssh systemctl start sshd.service systemctl enable sshd.service Editamos el archivo de configuración de ssh. vim /etc/ssh/sshd_config # Puerto # Linea 17, descomentar y cambiar puerto por defecto Port 50022 # Permitir login con root? # line 48: uncomment and change 'no' PermitRootLogin no # line 77: uncomment PermitEmptyPasswords no # Disable password authentication forcing use of keys # line 78: PasswordAuthentication yes # Usuarios a los que se les permite conectarse # Añadir al final AllowUsers usuario1 usuario2 usuarioX Crear una clave rsa, desde el cliente/clientes ssh-keygen -t rsa -b 4096 # Agregar clave SSH al agente ssh (evitar tener que poner el passphrase siempre) ssh-add Si ssh-add devuelve Could not open a connection to your authentication agent. eval `ssh-agent -s` ssh-add Subirla al servidor scp .ssh/id_rsa.pub usuario@SERVER_IP_ADDRESS: O tambien es posible insertarla con ssh-copy-id ssh-copy-id usuario@SERVER_IP_ADDRESS ssh-copy-id -p PUERTO usuario@SERVER_IP_ADDRESS En el servidor, como usuario mkdir .ssh chmod 700 .ssh touch .ssh/authorized_keys chmod 600 .ssh/authorized_keys cat id_rsa.pub > .ssh/authorized_keys 3.2. Fedora Centos 25 Apuntes Informatica Documentation, Publicación 1.0.0 Firewalld firewall-cmd --permanent --zone=public --add-service=ssh # Si es un puerto distinto al 22 firewall-cmd --permanent --zone=public --add-port=puerto/tcp firewall-cmd --reload SELinux Si es un puerto distinto al 22 semanage port -a -t ssh_port_t -p tcp PUERTO_NUEVO Si se ha cambiado el puerto, para entrar por ssh ssh -p PUERTO usuario@SERVER_IP_ADDRESS 3.2.6 Repositorios Copr Nodejs https://copr.fedoraproject.org/coprs/nibbler/nodejs/ # Versión LTS dnf copr -y enable nibbler/nodejs4 # Ultima versión dnf copr -y enable nibbler/nodejs dnf update -y dnf install -y nodejs npm Neovim https://copr.fedorainfracloud.org/coprs/dperson/neovim/ dnf copr -y enable dperson/neovim dnf update -y dnf install -y neovim terminix https://github.com/gnunn1/terminix#install-terminix dnf copr enable heikoada/terminix dnf update -y dnf install -y terminix 3.2.7 Crear SSL cd /etc/pki/tls/certs make snicoper.key 26 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Introducir passphrase umask 77 ; \ /usr/bin/openssl genrsa -aes128 2048 > snicoper.key openssl rsa -in snicoper.key -out snicoper.key make snicoper.csr Los datos que le pongo (Son para servidor de pruebas!) Country Name (2 letter code) [XX]:es State or Province Name (full name) []:Spain Locality Name (eg, city) [Default City]:Barcelona Organization Name (eg, company) [Default Company Ltd]:snicoper Organizational Unit Name (eg, section) []:Web service Common Name (eg, your name or your server's hostname) []:ns1 Email Address []:snicoper@gmail.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:(vacio) An optional company name []: (vacio) openssl x509 -in snicoper.csr -out snicoper.crt -req -signkey snicoper.key -days 3650 chmod 400 snicoper.* 3.2.8 Eliminar Kernel Antiguos Peligro: Cuidado de no eliminar el que se esta usando, nunca me ha pasado, pero no se si lo permitiria. Fuentes http://my.opera.com/man666/blog/quitar-kernels-antiguos-en-fedora Como usuario root, para ver todos los kernels instalados rpm -qa | grep kernel- Para eliminar el o los kernels viejos rpm -e kernel-2.6.38.2-9.fc15.x86_64 3.2.9 Escanear redes conectadas en Lan sudo yum -y install arp-scan sudo arp-scan --interface=p2p1 --localnet 3.2. Fedora Centos 27 Apuntes Informatica Documentation, Publicación 1.0.0 3.2.10 Firewall Basico Referencias https://fedoraproject.org/wiki/FirewallD#Using_firewall-cmd http://ktaraghi.blogspot.com.es/2013/10/what-is-firewalld-and-how-it-works.html http://liquidat.wordpress.com/2013/04/09/howto-firewalld-basics/ http://www.tecmint.com/firewalld-rules-for-centos-7/2/ drop (Inmutable): Los paquetes de red entrantes se cae, no hay respuesta. Sólo las conexiones de red salientes son posibles. block: Las conexiones de red entrantes se rechazarán con un mensaje icmp-host-prohibited para IPv4 e icmp6adm-prohibido para IPv6. Sólo las conexiones de red iniciadas dentro de este sistema son posibles. external: Para su uso en redes externas con enmascaramiento habilitado especialmente para los routers. Usted no confía en los otros equipos de redes para no dañar su equipo. Sólo seleccionados conexiones entrantes son aceptadas. dmz: Para los equipos de la zona de distensión que son de acceso público con acceso limitado a la red interna. Sólo seleccionados conexiones entrantes son aceptadas. work: Para el uso en las áreas de trabajo. Que en su mayoría confían en los otros equipos de redes para no dañar su equipo. Sólo seleccionados conexiones entrantes son aceptadas. home: Para su uso en zonas de origen. Que en su mayoría confían en los otros equipos de redes para no dañar su equipo. Sólo seleccionados conexiones entrantes son aceptadas. internal: Para su uso en redes internas. Que en su mayoría confían en los otros equipos de la red para no dañar su equipo. Sólo seleccionados conexiones entrantes son aceptadas. trusted: Todas las conexiones de red son aceptadas. Saber el estado del servicio firewall-cmd --state Obtener el listado de zonas firewall-cmd --get-zones Saber la zona activada por defecto firewall-cmd --get-default-zone Listar puertos o servicios abiertos firewall-cmd --zone=public --list-ports firewall-cmd --zone=public --list-services Poner zona por defecto firewall-cmd --set-default-zone=public Añadir un puerto de manera persistente 28 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 firewall-cmd --permanent --zone=public --add-port=80/tcp Añadir un rango de puertos firewall-cmd --permanent --zone=public --add-port=2000-2010/tcp Añadir un servicio de manera persistente firewall-cmd --permanent --zone=public --add-service=http Para eliminar cabiar –add-x por –remove-x Permitir conexion a la red local. sudo firewall-cmd --permanent --zone="trusted" --add-source="192.168.1.0/24" Bloquear una ip firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.0.250" reject' firewall-cmd --zone=public --list-all Eliminar bloqueo a la ip firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.0.250" reje firewall-cmd --zone=public --list-all Redireccionar un puerto https://ask.fedoraproject.org/en/question/32104/port-redirect-with-firewalld/ Me funciono solo con la siguiente linea, no es permanente. firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080 3.2.11 Fuente Ubuntu Fuentes: http://font.ubuntu.com/ unzip ubuntu-font-family-0.80.zip sudo mv ubuntu-font-family-0.80 /usr/share/fonts/ubuntu-font-family 3.2.12 Post instalación Centos 7 Nota: Centos 7 Minimal. Todo como super usuario. Crear usuario y añadir a wheel adduser snicoper passwd snicoper usermod -aG wheel snicoper 3.2. Fedora Centos 29 Apuntes Informatica Documentation, Publicación 1.0.0 hostname hostnamectl --static set-hostname fqdn.host.name Timezone timedatectl set-timezone Europe/Madrid Cambiar Keyboard Layout (keymap) localectl list-keymaps | grep es Para cambiar a es localectl set-keymap es REMI y EPEL RHEL/CentOS 7 # epel yum install epel-release # remi yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm Actualizar el sistema yum -y update Programas básicos yum -y install \ bash-completion \ cpp \ firewalld \ gcc \ git \ htop \ kernel-devel \ kernel-headers \ make \ mutt \ net-tools \ openssh \ policycoreutils-python \ vim \ wget \ yum-utils 30 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.2.13 Post instalacion Fedora Fedora 24 Workstation Gnome Settings # Wallpaper, requiere tener el wallpaper en el directorio que indica. # gsettings set org.gnome.desktop.background picture-uri '/home/snicoper/Pictures/Wallpapers/f25/defa gsettings set org.gnome.desktop.background picture-uri '/home/snicoper/Pictures/Wallpapers/Xplo_by_Hu # General gsettings gsettings gsettings gsettings gsettings set set set set set org.gnome.desktop.interface clock-show-date true org.gnome.desktop.interface gtk-theme 'Adwaita' org.gnome.desktop.screensaver lock-enabled false org.gnome.desktop.session idle-delay 900 org.gnome.desktop.wm.preferences button-layout 'appmenu:minimize,close' # Gedit gsettings gsettings gsettings gsettings gsettings gsettings gsettings gsettings set set set set set set set set org.gnome.gedit.preferences.editor org.gnome.gedit.preferences.editor org.gnome.gedit.preferences.editor org.gnome.gedit.preferences.editor org.gnome.gedit.preferences.editor org.gnome.gedit.preferences.editor org.gnome.gedit.preferences.editor org.gnome.gedit.preferences.editor # Desktop gsettings gsettings gsettings gsettings gsettings set set set set set org.gnome.desktop.background show-desktop-icons true org.gnome.nautilus.desktop home-icon-visible true org.gnome.nautilus.desktop network-icon-visible false org.gnome.nautilus.desktop trash-icon-visible false org.gnome.nautilus.desktop volumes-visible false # Nautilus gsettings set gsettings set gsettings set gsettings set gsettings set auto-indent true bracket-matching true highlight-current-line true insert-spaces true scheme 'solarized-dark' tabs-size 4 wrap-last-split-mode 'word' wrap-mode 'none' org.gnome.nautilus.icon-view default-zoom-level 'standard' org.gnome.nautilus.list-view use-tree-view true org.gnome.nautilus.preferences default-folder-viewer 'icon-view' org.gnome.nautilus.preferences sort-directories-first true org.gnome.nautilus.window-state geometry '890x413+42+299' # Fuentes gsettings set org.gnome.desktop.interface monospace-font-name 'Dejavu Sans Mono 11' gsettings set org.gnome.settings-daemon.plugins.xsettings antialiasing 'rgba' gsettings set org.gnome.settings-daemon.plugins.xsettings hinting 'slight' gsettings set org.gnome.settings-daemon.plugins.xsettings overrides "{'Gtk/ButtonImages': <1>, 'Gtk/M Paper Theme Ver dotfiles 3.2. Fedora Centos 31 Apuntes Informatica Documentation, Publicación 1.0.0 Terminix dnf copr enable heikoada/terminix dnf install -y terminix terminix-nautilus profile -> color -> Material Global Dark Theme cat >> ~/.config/gtk-3.0/settings.ini << EOF [Settings] gtk-application-prefer-dark-theme=1 EOF Reloguear Eliminar algunos dnf remove -y \ rhythmbox \ evolution \ shotwell Actualizar dnf update -y RPMFusion http://rpmfusion.org/Configuration dnf install -y https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-25.noarch.rpm dnf install -y https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-25.noarch.rpm dnf update -y Codecs dnf -y install \ gstreamer-plugins-bad \ gstreamer-plugins-bad-free-extras \ gstreamer-plugins-bad-nonfree gstreamer-plugins-ugly \ gstreamer-ffmpeg \ gstreamer1-libav \ gstreamer1-plugins-bad-free-extras \ gstreamer1-plugins-bad-freeworld \ gstreamer1-plugins-base-tools \ gstreamer1-plugins-good-extras \ gstreamer1-plugins-ugly \ gstreamer1-plugins-bad-free \ gstreamer1-plugins-good \ 32 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 gstreamer1-plugins-base \ gstreamer1 Flash Player ## Adobe Repository 64-bit x86_64 ## rpm -ivh http://linuxdownload.adobe.com/adobe-release/adobe-release-x86_64-1.0-1.noarch.rpm rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-adobe-linux dnf install -y flash-plugin Programas básicos dnf -y install \ chromium \ cloc \ cpp \ ctags \ ctags-etags \ dconf-editor \ dia \ gcc \ gcc-c++ \ geary \ gimp \ git \ gitg \ gparted \ gpick \ htop \ hunspell-es \ kernel-devel \ kernel-headers \ make \ meld \ mutt \ nmap \ p7zip \ p7zip-plugins \ pwgen \ transmission \ vim \ wget \ yumex-dnf Para pwgen pwgen -sy 16 Opcionales # Otros dnf -y install dnf -y install dnf -y install dnf -y install dnf -y install java-1.8.0-openjdk-devel adobe-source-code-pro-fonts levien-inconsolata-fonts gnome-tweak-tool unrar 3.2. Fedora Centos 33 Apuntes Informatica Documentation, Publicación 1.0.0 dnf dnf dnf dnf dnf dnf dnf dnf dnf dnf -y -y -y -y -y -y -y -y -y -y install install install install install install install install install install zsh breeze-icon-theme gedit-plugins gnome-builder gnome-calendar gnome-music gnome-photos gnome-todo gnome-terminal-nautilus inkscape Firewalld Poner por defecto zone=public y añadir la red local a trusted firewall-cmd firewall-cmd firewall-cmd firewall-cmd firewall-cmd --set-default-zone=public --zone=public --list-ports --permanent --zone=trusted --add-source=192.168.1.0/24 --reload --zone=trusted --list-sources Idiomas vim /etc/locale.conf LANG=en_US.UTF-8 LC_NUMERIC=es_ES.UTF-8 LC_TIME=es_ES.UTF-8 LC_MONETARY=es_ES.UTF-8 LC_PAPER=es_ES.UTF-8 LC_MEASUREMENT=es_ES.UTF-8 LC_CTYPE=es_ES.UTF-8 LC_COLLATE=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LC_NAME=es_ES.UTF-8 LC_ADDRESS=es_ES.UTF-8 LC_TELEPHONE=es_ES.UTF-8 LC_IDENTIFICATION=es_ES.UTF-8 Post post instalacion Instalación Python en Fedora Instalación de PostgreSQL Instalación de Postgis Apuntes PIP Postfix Instalación NodeJS Actualizar todos los paquetes de Pip Contar lineas de un proyecto 34 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Chromium español linux 3.2.14 Postfix Nota: Probado en Fedora 24, Centos 7 Las lineas entre parentesis ‘(x)’, son las de Centos. Servidor postfix Instalación de postfix. dnf install -y postfix dovecot Editar archivo de configuración. vim /etc/postfix/main.cf # line 94 (75): uncomment and specify hostname myhostname = mail.snicoper.local # line 102 (83): uncomment and specify domain name mydomain = snicoper.local # line 118 (99): uncomment myorigin = $mydomain # line 132 (113): uncomment inet_interfaces = all # line 135 (116): comment # inet_interfaces = localhost # line 183 (164): comentar #mydestination = $myhostname, localhost.$mydomain, localhost # line 184 (165): descomentar mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain # line 283 (264): uncomment and specify your LAN mynetworks = 192.168.1.0/24, 127.0.0.0/8 # line 438 (419): uncomment (use Maildir) home_mailbox = Maildir/ # line 593 (574): add smtpd_banner = $myhostname ESMTP # add at the last line # limit an email size 10M message_size_limit = 10485760 3.2. Fedora Centos 35 Apuntes Informatica Documentation, Publicación 1.0.0 # limit mailbox 1G mailbox_size_limit = 1073741824 # for SMTP-Auth settings smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = $myhostname # http://serverfault.com/questions/775415/postfix-noqueue-reject-rcpt-from-unknown #smtpd_client_restrictions = permit_mynetworks,reject_unknown_client,permit #smtpd_recipient_restrictions = permit_mynetworks,permit_auth_destination,permit_sasl_authenticated,r smtpd_recipient_restrictions = permit_sasl_authenticated, reject_unauth_destination smtpd_sender_restrictions = reject_unknown_sender_domain Dovecot vim /etc/dovecot/dovecot.conf # line 24: uncomment protocols = imap pop3 lmtp vim /etc/dovecot/conf.d/10-auth.conf # line 10: uncomment and change ( allow plain text auth ) disable_plaintext_auth = no # line 100: add 'login' auth_mechanisms = plain login vim /etc/dovecot/conf.d/10-mail.conf # line 30: uncomment and add mail_location = maildir:~/Maildir vim /etc/dovecot/conf.d/10-master.conf # line 96: uncomment and add # Postfix smtp-auth unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix # add group = postfix # add } vim /etc/aliases # En la ultima linea agregar root: snicoper postalias /etc/aliases newaliases Importante: 36 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Ver Reglas SELinux Para crear el certificado SSL, Crear SSL vim /etc/postfix/main.cf # add at the last line # SSL smtpd_use_tls = yes smtpd_tls_cert_file = /etc/pki/tls/certs/snicoper.crt smtpd_tls_key_file = /etc/pki/tls/certs/snicoper.key smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache vim /etc/postfix/master.cf # Descomentar linea 28 (26) smtps inet n - n - - smtpd # Descomentar lineas 29 (27) y 30 (28) -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes vim /etc/dovecot/conf.d/10-ssl.conf # line 8: uncomment ssl = yes # line 14,15: comentar # line 16: añadir and specify certificate ssl_cert = </etc/pki/tls/certs/snicoper.crt ssl_key = </etc/pki/tls/certs/snicoper.key systemctl systemctl systemctl systemctl start postfix.service enable postfix.service start dovecot.service enable dovecot.service Poner por defecto (si no lo esta) postfix alternatives --config mta Firewall firewall-cmd --permanent --zone=public --add-service=smtp firewall-cmd --reload Lista de puertos por defecto POP3 - port 110 IMAP - port 143 SMTP - port 25 HTTP - port 80 Secure SMTP (SSMTP) - port 465 Secure IMAP (IMAP4-SSL) - port 585 IMAP4 over SSL (IMAPS) - port 993 Secure POP3 (SSL-POP) - port 995 3.2. Fedora Centos 37 Apuntes Informatica Documentation, Publicación 1.0.0 3.2.15 Reglas SELinux Virt-Manager y Boxes (Cajas) setsebool -P virt_use_fusefs 1 setsebool -P virt_use_rawip 1 Bind setsebool -P named_write_master_zones 1 Postfix Para permitir a Apache poder enviar correo electrónico desde alguna aplicación setsebool -P httpd_can_sendmail 1 setsebool -P httpd_read_user_content 1 Postgresql setsebool -P allow_user_postgresql_connect 1 Memcached setsebool -P httpd_can_network_memcache 1 Apache2.4 y Nginx Para permitir que Apache/Nginx pueda leer contenidos localizados en los directorios de los usuarios. setsebool -P httpd_enable_homedirs 1 setsebool -P httpd_read_user_content 1 setsebool -P httpd_can_network_connect 1 Para definir que un directorio fuera de /var/www, como por ejemplo /sitios/dominio.tld/html, pueda ser utilizado por Apache, se le debe asignar el contexto httpd_sys_content_t. Éste puede asignarse a través del mandato chcon, como se muestra en el siguiente ejemplo chcon -t httpd_sys_content_t /sitios/dominio.tld/htm # ls -Z para saber el contexto 3.2.16 Reinstalar GRUB despues de instalar windows Fuentes: http://www.supergrubdisk.org/super-grub2-disk/ https://ask.fedoraproject.org/en/question/60906/problem-reinstalling-grub2-fedora-21/ 38 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Super Grub2 Disk Con Super Grub2 Disk Con la LIVE de Fedora sudo fdisk -l # Ver particion donde esta linux. sudo mount /dev/sda6 /mnt sudo sudo sudo sudo mount mount mount mount --bind --bind --bind --bind /dev /mnt/dev && /dev/pts /mnt/dev/pts && /proc /mnt/proc && /sys /mnt/sys sudo chroot /mnt # sudo grub2-mkconfig -o /boot/grub2/grub.cfg ; #if needed sudo grub2-install /dev/sda ;#taking sda as the sata disk 3.2.17 Virt-Manager Fuentes http://fedoraproject.org/wiki/Getting_started_with_virtualization/es http://www.cyberciti.biz/faq/linux-kvm-stop-start-guest-virtual-machine/ http://pic.dhe.ibm.com/infocenter/lnxinfo/v3r0m0/index.jsp?topic=%2Fliaat%2Fliaatkvmvirsh.htm yum install @virtualization yum install libvirt-daemon-kvm Ver Reglas SELinux systemctl enable libvirtd.service Importante: Reiniar el equipo Como usuario normal, crear una maquina virtual virt-install --name ns2.workspace.local --ram 1024 \ --file=/home/snicoper/kvm/ns2.workspace.local.img \ --file-size=8 --vnc \ --cdrom=/run/media/snicoper/data/snicoper/Distros_Linux/CentOS-6.4-x86_64-bin-DVD1to2/CentOS-6.4- O bien virt-install --prompt Nombre de la maquina: ns2.workspace.local Ram utilizada (en megas): 1024 Path donde guardara la maquina: /home/snicoper/kvm/ns2.workspace.local.img 3.2. Fedora Centos 39 Apuntes Informatica Documentation, Publicación 1.0.0 Disco duro en Gigas para la maquina: 8 Path de la imagen iso: /ruta/imagen.iso Algunos comandos Listar VMS funcionando virsh list Apagar Guest virsh list virsh shutdown Name virsh shutdown Id Reiniciar Guest virsh list virsh reboot Name virsh reboot Id Forzar apagado virsh list virsh destroy Name virsh destroy Id Optener información sobre un Guest virsh list virsh dominfo Name virsh dominfo Id Obtener información sobre el nodo virsh nodeinfo Eliminar una maquina Este lo hice a mano por que no me funciono. virsh destroy ns2.workspace.local virsh undefine ns2.workspace.local virsh vol-delete --pool vg0 ns2.workspace.local.img 40 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Iniciar la maquina virsh start ns2.workspace.local Mostrarla virt-viewer ns2.workspace.local 3.2.18 Virtualbox Fuentes http://www.if-not-true-then-false.com/2010/install-virtualbox-with-yum-on-fedora-centos-red-hat-rhel/ Para versiones Fedora < 22 o Centos, ver el enlace de Fuentes, aquí solo me pongo la de Fedora (22) # Repo cd /etc/yum.repos.d/ wget http://download.virtualbox.org/virtualbox/rpm/fedora/virtualbox.repo # Actualizar dnf update # Dependencias dnf install binutils gcc make patch libgomp glibc-headers glibc-devel kernel-headers kernel-devel dkm # Instalar dnf install VirtualBox-5.0 # Inicializar # /etc/init.d/vboxdrv setup /usr/lib/virtualbox/vboxdrv.sh setup # Dar permisos a usuario usermod -a -G vboxusers snicoper 3.3 MariaDB Contents: 3.3.1 Instalación MariaDB En Fedora 20+, MySQL Workbench no esta en los repositorios, tampoco he probado Workbench con MariaDB 10+ en ningún sistema. Fedora 3.3. MariaDB 41 Apuntes Informatica Documentation, Publicación 1.0.0 yum -y install mariadb mariadb-server # Opcional yum -y install mysql-workbench systemctl start mariadb.service systemctl enable mariadb.service mysql_secure_installation Ubuntu En Ubuntu, hay que instalarlo con los repos de MariaDB: https://downloads.mariadb.org/mariadb/repositories/#mirror=cnrs sudo apt-get install software-properties-common sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db sudo add-apt-repository 'deb http://ams2.mirrors.digitalocean.com/mariadb/repo/10.1/ubuntu trusty mai sudo apt-get update sudo apt-get install mariadb-server # Opcional apt-get install mysql-workbench Ejecutar, para eliminar usuario temporal, etc mysql_secure_installation /etc/init.d/mysql restart Crear un usuario y una database mysql -u root -p CREATE USER snicoper@localhost IDENTIFIED BY '123456'; CREATE DATABASE practicas; GRANT ALL ON practicas.* TO snicoper@localhost; 3.4 MySQL 3.4.1 Instalación MySQL Ubuntu sudo apt-get install mysql-server sudo mysql_secure_installation Crear un usuario y una database mysql -u root -p CREATE USER snicoper@localhost IDENTIFIED BY '123456'; CREATE DATABASE practicas; GRANT ALL ON practicas.* TO snicoper@localhost; 42 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.5 Nginx Contents: 3.5.1 Authentication HTTP Nginx Fuentes https://www.digitalocean.com/community/tutorials/how-to-set-up-basic-http-authentication-with-nginx-oncentos-7 su yum install -y httpd-tools cd /etc/nginx/ # Donde el nginx es el nombre que despues pedira # y .htpasswd el archivo que generara. htpasswd -c /etc/nginx/.htpasswd nginx Editar en el servidor: vim /etc/nginx/conf.d/archivo_configuracion.conf server { listen listen server_name root 80 default_server; [::]:80 default_server; _; /usr/share/nginx/html; auth_basic "Private Property"; auth_basic_user_file /etc/nginx/.htpasswd; # .... systemctl reload nginx 3.5.2 Instalación Nginx Ubuntu Instalación sudo apt install nginx sudo service nginx start Si se quiere permitir que puedan verse las paginas desde fuera del localhost añadir regla en ufw sudo ufw allow 80 Ubuntu PPA https://launchpad.net/~nginx/+archive/ubuntu/development 3.5. Nginx 43 Apuntes Informatica Documentation, Publicación 1.0.0 http://wiki.nginx.org/Install sudo -s nginx=stable # use nginx=development for latest development version sudo add-apt-repository ppa:nginx/$nginx sudo apt-get update sudo apt-get install nginx Fedora Instalación dnf install -y nginx Centos Nota: Tambien estan en los repos de remi Post instalación Centos 7 vim /etc/yum.repos.d/nginx.repo Añadir [nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=0 enabled=1 yum update yum install -y nginx Fedora y Centos systemctl start nginx.service systemctl enable nginx.service Firewall firewall-cmd --permanent --zone=public --add-service=http firewall-cmd --permanent --zone=public --add-service=https firewall-cmd --reload Si se crea un host en el home, se ha de dar permisos 711 al home del usuario chmod 711 /home/snicoper Ver Reglas SELinux 3.5.3 Nginx Gunicorn Django Socket Servir un sitio Web Django con gunicorn y Nginx es algo que tarde o temprano todos hacemos, aunque solo sea para ver como responde nuestro sitio antes de ponerlo en producción y lidiar con los problemas que nos podemos encontrar cuando de verdad lo subamos a un servidor. 44 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Esta es una configuración básica que funciona muy bien. En primer lugar, instalamos nginx sudo dnf install nginx Primero creamos un entorno virtual con virtualenvwrapper. mkvirtualenv practica El resto del ejemplo, estaremos usando el entorno virtual practica. Instalar Django y Gunicorn con pip. pip install django pip install gunicorn Creamos un directorio para todo el proyecto en ~/webapps/ yo para los ejemplos, uso mi usuario snicoper, tu siempre pon tu usuario!. cd ~/webapps mkdir example.com Creamos unos directorios dentro de example.com cd example.com mkdir bin run Y ahora, creamos el proyecto Django, también dentro de example.com django-admin startproject example Esto nos crea el típico proyecto Django . -- bin -- example | -- example | | -- __init__.py | | -- settings.py | | -- urls.py | | -- wsgi.py | -- manage.py -- run Crearemos un archivo gunicorn_start.sh en el directorio bin/. vim bin/gunicorn_start.sh y añadimos las siguientes lineas #!/bin/bash NAME="example.com" # Name of the application DJANGODIR=/home/snicoper/webapps/example.com/example # Django project directory LOGFILE=/var/log/gunicorn/gunicorn.log LOGDIR=$(dirname $LOGFILE) SOCKFILE=/home/snicoper/webapps/example.com/run/gunicorn.sock # we will communicte using this unix so USER=snicoper # the user to run as GROUP=snicoper # the group to run as NUM_WORKERS=3 # how many worker processes should Gunicorn spawn DJANGO_SETTINGS_MODULE=example.settings # which settings file should Django use 3.5. Nginx 45 Apuntes Informatica Documentation, Publicación 1.0.0 DJANGO_WSGI_MODULE=example.wsgi # WSGI module name echo "Starting $NAME as `whoami`" # Activate the virtual environment source /home/snicoper/.virtualenvs/example.com/bin/activate export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE export PYTHONPATH=$DJANGODIR:$PYTHONPATH # Create the run directory if it doesn't exist RUNDIR=$(dirname $SOCKFILE) test -d $RUNDIR || mkdir -p $RUNDIR # Start your Django Unicorn # Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon) exec gunicorn ${DJANGO_WSGI_MODULE}:application \ --name $NAME \ --workers $NUM_WORKERS \ --user=$USER --group=$GROUP \ --bind=unix:$SOCKFILE \ --log-level=debug \ --log-file=$LOGFILE 2>>$LOGFILE Actualizar las rutas y usuario/grupo del script, y le damos permisos de ejecución. chmod +x bin/gunicorn_start.sh Crear directorio /var/log/gunicorn y dentro, el archivo gunicorn.log sudo mkdir /var/log/gunicorn sudo chown snicoper:snicoper /var/log/gunicorn touch /var/log/gunicorn/gunicorn.log Y por ultimo, configurar un servidor virtual etc/nginx/conf.d/example.com.conf de nginx, para ello, creamos un archivo en sudo vim etc/nginx/conf.d/example.com.cof Y añadimos lo siguiente, una vez mas, asegurase que las rutas son las correctas y el usuario. upstream example_app_server { # fail_timeout=0 means we always retry an upstream even if it failed # to return a good HTTP response (in case the Unicorn master nukes a # single worker for timing out). server unix:/home/snicoper/webapps/example.com/run/gunicorn.sock fail_timeout=0; } server { listen 80; server_name example.com; client_max_body_size 4G; access_log /var/log/nginx/example.com-access.log; error_log /var/log/nginx/example.com-error.log; location /static/ { 46 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 alias /home/snicoper/webapps/example.com/static/; } location /media/ { alias /home/snicoper/webapps/example.com/media/; } location / { # an HTTP header important enough to have its own Wikipedia entry: # http://en.wikipedia.org/wiki/X-Forwarded-For proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # enable this if and only if you use HTTPS, this helps Rack # set the proper protocol for doing redirects: # proxy_set_header X-Forwarded-Proto https; # pass the Host: header from the client right along so redirects # can be set properly within the Rack application proxy_set_header Host $http_host; # we don't want nginx trying to do something clever with # redirects, we set the Host: header above already. proxy_redirect off; # # # # # # set "proxy_buffering off" *only* for Rainbows! when doing Comet/long-poll stuff. It's also safe to set if you're using only serving fast clients with Unicorn + nginx. Otherwise you _want_ nginx to buffer responses to slow clients, really. proxy_buffering off; # Try to serve static files from nginx, no point in making an # *application* server like Unicorn/Rainbows! serve static files. if (!-f $request_filename) { proxy_pass http://example_app_server; break; } } # Error pages error_page 500 502 503 504 /500.html; location = /500.html { root /home/snicoper/webapps/example.com/templates/; } } Reiniciamos el servidor nginx con sudo systemctl start nginx.service # Si lo queremos como servicio. sudo systemctl enable nginx.service Abrir el puesto 80 sudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --reload Para la practica, el puerto no es necesario, pero hay queda :), y ahora le en /etc/hosts le decimos que 3.5. Nginx 47 Apuntes Informatica Documentation, Publicación 1.0.0 example.com apunte a 127.0.0.1 sudo vim /etc/hosts # Añadimos 127.0.0.1 example.com Primero lo probamos manualmente cd ~/webapps/example.com/bin ./gunicorn_start.sh Entramos a [http://example.com](http://example.com) Lo mas seguro que SELinux se queje con algo así SELinux is preventing nginx from write access on the sock_file gunicorn.sock.. Yo, para solucionar eso hice lo siguiente: cd ~/webapps/example.com/run/ sudo grep nginx /var/log/audit/audit.log | audit2allow -M nginx sudo semodule -i nginx.pp Ya con eso, me funciono bien. Ahora, ya solo nos falta poner que gunicorn_start.sh se inicie al reiniciar la maquina y poderlo reiniciar de una manera rápida. Casi todo el mundo lo hace con supervisor, pero yo probé creando un servicio systemd y me funciona muy bien, así que es como lo voy a poner. sudo vim /etc/systemd/system/gunicorn.service Y añadimos los siguiente [Unit] Description=gunicorn daemon After=syslog.target After=network.target [Service] PIDFile=/run/gunicorn/pid User=snicoper Group=snicoper WorkingDirectory=/home/snicoper/webapps/example.com/bin/ ExecStart=/bin/bash gunicorn_start.sh ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target Para reiniciar, etc, se usa los típicos comandos de systemd sudo sudo sudo sudo systemctl systemctl systemctl systemctl start gunicorn.service stop gunicorn.service restart gunicorn.service enable gunicorn.service Esta configuración ha sido por socket entre gunicorn y nginx, pero tambien es posible hacerlo por IP, tengo unos [apuntes sobre el tema](http://apuntes-snicoper.readthedocs.org/es/latest/linux/nginx/nginx_gunicorn_django.html). 48 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 — Fuentes [http://gunicorn-docs.readthedocs.org/en/latest/index.html](http://gunicorn-docs.readthedocs.org/en/latest/index.html) [https://gist.github.com/postrational/5747293](https://gist.github.com/postrational/5747293) [http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenvsupervisor/](http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/) [http://superuser.com/questions/809527/nginx-cant-connect-to-uwsgi-socket-with-correctpermissions](http://superuser.com/questions/809527/nginx-cant-connect-to-uwsgi-socket-with-correctpermissions) 3.5.4 Instalación Nginx, Gunicorn y Django Fuentes http://goodcode.io/blog/django-nginx-gunicorn/ http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/ https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-django-with-postgres-nginxand-gunicorn Gunicorn En proyect_name/bin, creamos un archivo gunicorn_start.sh vim bin/gunicorn_start.sh # Añadimos #!/bin/bash NAME="proyect_name" # Name of the application DJANGODIR=/home/snicoper/projects/python/proyect_name/src/ # Django project directory LOGFILE=/home/snicoper/projects/python/proyect_name/logs/gunicorn.log LOGDIR=$(dirname $LOGFILE) USER=snicoper # the user to run as GROUP=snicoper # the group to run as ADDRESS=127.0.0.1:8001 NUM_WORKERS=3 # how many worker processes should Gunicorn spawn DJANGO_SETTINGS_MODULE=settings.settings_prod # which settings file should Django use DJANGO_WSGI_MODULE=settings.wsgi # WSGI module name echo "Starting $NAME as `whoami`" # Activate the virtual environment cd $DJANGODIR source /home/snicoper/.virtualenvs/default/bin/activate export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE export PYTHONPATH=$DJANGODIR:$PYTHONPATH # Start your Django Unicorn # Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon) 3.5. Nginx 49 Apuntes Informatica Documentation, Publicación 1.0.0 exec gunicorn ${DJANGO_WSGI_MODULE}:application \ --workers $NUM_WORKERS \ --bind=$ADDRESS \ --user=$USER --group=$GROUP \ --log-level=debug \ --log-file=$LOGFILE 2>>$LOGFILE Advertencia: Corregir las rutas y usuario! Permisos de ejecución chmod +x bin/gunicorn_start.sh Nginx Instalación Nginx Nota: En Fedora/Centos si se sirven las paginas en el home hay que dar pemisos al home del usuario chmod 711 /home/usuario # Ubuntu sudo vim /etc/nginx/sites-avalaible/proyect_name # Fedora/Centos sudo vim /etc/nginx/conf.d/proyect_name.conf Añadimos server { listen 80; server_name www.workspace.local; access_log /var/log/nginx/proyect_name-access.log; error_log /var/log/nginx/proyect_name-error.log; # Django media location /media/ { alias /home/snicoper/projects/python/proyect_name/src/media/; } # your Django project's media # Django static location /static/ { alias /home/snicoper/projects/python/proyect_name/src/static/; # your Django project's static } # Django static admin location /static/admin/ { # this changes depending on your python version alias /home/snicoper/.virtualenvs/default/lib/python3.4/site-packages/django/contrib/admin/st } location / { proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; 50 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_connect_timeout 10; proxy_read_timeout 10; proxy_pass http://localhost:8001/; } # what to serve if upstream is not available or crashes error_page 500 502 503 504 /templates/50x.html; } # Solo Ubuntu sudo ln -s /etc/nginx/sites-avalaible/proyect_name /etc/nginx/sites-enabled/proyect_name Si los archivos static no se ven, mirar collectstatic de Django, o modificar location /static/admin/ En Fedora/Centos, mirar Reglas SELinux y si el proyecto esta en el home de un usuario, poner permisos 711 en la carpeta del usuario, de lo contrario, mostrara un error 403 Reiniciar nginx # Ubuntu sudo service nginx restart # Fedora/Centos systemctl restart nginx.service Supervisor Ubuntu sudo apt-get install supervisor sudo touch /etc/supervisor/conf.d/proyect_name.conf Añadir en proyect_name.conf [program:proyect_name] command=/home/snicoper/projects/python/proyect_name/bin/gunicorn_start.sh user=snicoper stdout_logfile=/home/snicoper/projects/python/proyect_name/logs/gunicorn_supervisor.log redirect_stderr=true autostart=true autorestart=true Crear archivo de log mkdir /home/snicoper/projects/python/proyect_name/logs touch /home/snicoper/projects/python/proyect_name/logs/gunicorn_supervisor.log sudo supervisorctl reread sudo supervisorctl update Comandos supervisor sudo sudo sudo sudo supervisorctl supervisorctl supervisorctl supervisorctl 3.5. Nginx status proyect_name stop proyect_name start proyect_name restart proyect_name 51 Apuntes Informatica Documentation, Publicación 1.0.0 Systemd Fedora/Centos7 como servicio sudo vim /etc/systemd/system/gunicorn.service [Unit] Description=gunicorn daemon After=syslog.target After=network.target [Service] PIDFile=/run/gunicorn/pid User=snicoper Group=snicoper WorkingDirectory=/home/snicoper/www/sitio/bin/ ExecStart=/bin/bash gunicorn_start.sh ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target sudo sudo sudo sudo systemctl systemctl systemctl systemctl start gunicorn.service stop gunicorn.service restart gunicorn.service enable gunicorn.service 3.5.5 PhpMyAdmin Virtualhost en Nginx Tener instalado MySQL o MariaDB + PHP. Fedora sudo vim /etc/nginx/conf.d/phpmyadmin.local.conf server { listen 80; server_name phpmyadmin.local; access_log /var/log/nginx/phpmyadmin_access.log; error_log /var/log/nginx/phpmyadmin_error.log; root /usr/share/phpMyAdmin; location / { index index.php; } ## Images and static content is treated different location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ { access_log off; expires 360d; } location ~ /\.ht { deny all; 52 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 } location ~ /(libraries|setup/frames|setup/libs) { deny all; return 404; } location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/share/phpMyAdmin$fastcgi_script_name; } } systemctl restart nginx.service systemctl restart php-fpm.service Ubuntu vim /etc/nginx/sites-available/phpmyadmin server { listen 80; server_name phpmyadmin.local; access_log /var/log/nginx/phpmyadmin_access.log; error_log /var/log/nginx/phpmyadmin_error.log; root /usr/share/phpMyAdmin; location / { index index.php; } ## Images and static content is treated different location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ { access_log off; expires 360d; } location ~ /\.ht { deny all; } location ~ /(libraries|setup/frames|setup/libs) { deny all; return 404; } location ~ .php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include /etc/nginx/fastcgi_params; } } 3.5. Nginx 53 Apuntes Informatica Documentation, Publicación 1.0.0 ln -s /etc/nginx/sites-available/phpmyadmin /etc/nginx/sites-enabled/phpmyadmin sudo service nginx restart sudo service php5-fpm restart 3.5.6 PhpPgMyAdmin Virtualhost en Nginx Fedora vim /etc/nginx/conf.d/phppgadmin.local.conf server { listen 80; server_name phppgadmin.local; access_log /var/log/nginx/phppgadmin_access.log; error_log /var/log/nginx/phppgadmin_error.log; root /usr/share/phpPgAdmin/; location / { index index.php; } ## Images and static content is treated different location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ { access_log off; expires 360d; } location ~ /\.ht { deny all; } location ~ /(libraries|setup/frames|setup/libs) { deny all; return 404; } location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/share/phpPgAdmin$fastcgi_script_name; } } systemctl restart postgresql.service systemctl restart nginx.service systemctl restart php-fpm.service Ubuntu vim /etc/nginx/sites-available/phppgadmin 54 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 server { listen 80; server_name phppgadmin.local; access_log /var/log/nginx/phppgadmin_access.log; error_log /var/log/nginx/phppgadmin_error.log; root /usr/share/phpPgAdmin/; location / { index index.php; } ## Images and static content is treated different location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ { access_log off; expires 360d; } location ~ /\.ht { deny all; } location ~ /(libraries|setup/frames|setup/libs) { deny all; return 404; } location ~ .php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include /etc/nginx/fastcgi_params; } } ln -s /etc/nginx/sites-available/phppgadmin /etc/nginx/sites-enabled/phppgadmin service nginx restart service php5-fpm restart 3.5.7 Restringir una URL a IPs Fuentes https://www.nginx.com/resources/admin-guide/restricting-access/ Restringir acceso a una URL a cierta/s IPs server { # .... # Bloquear todas las ips a la administración # excepto a ips de la red local location ^~ /admin/ { proxy_pass http://127.0.0.1:8001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; 3.5. Nginx 55 Apuntes Informatica Documentation, Publicación 1.0.0 allow ip_1 o 192.168.1.0/24; allow ip_2; deny all; } # .... } 3.5.8 Rewrite PHP location / { index index.html index.htm index.php; if (!-e $request_filename) { rewrite /(.*)$ /index.php?uri=$1 last; break; } } 3.5.9 Vhosts en Nginx Ubuntu Como usuario mkdir ~/public_html sudo vim /etc/nginx/sites-available/workspace.local server { listen 80; server_name lxmaq2.workspace.local; access_log /var/log/nginx/workspace-access.log; error_log /var/log/nginx/workspace-error.log; root /home/snicoper/public_html; location / { index index.html index.htm index.php; } location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ { access_log off; log_not_found off; expires 360d; } # Si quiero que se vean los archivos y directorios cambiar a on autoindex on; location ~ .php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include /etc/nginx/fastcgi_params; 56 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 } } Copiar el sitio creado a sites-enabled sudo ln -s /etc/nginx/sites-available/workspace.local /etc/nginx/sites-enabled/workspace.local Si instalo phpmyadmin En Ubuntu además, hago un enlace simbólico de phpmyadmin en la carpeta home, para acceder luego a phpmyadmin http://www.workspace.local/phpmyadmin y me ahorro tener que crear un nuevo vhost para phpmyadmin. sudo ln -s ln -s /usr/share/phpmyadmin/ public_html/ Reiniciar los servicios. sudo service nginx restart sudo service php5-fpm restart Fedora Todo como root Nota: Si se crea un host virtual en el home del usuario, es necesario dar permisos 711 al directorio del usuario. mkdir chmod chmod chown /home/snicoper/public_html 711 /home/snicoper 755 /home/snicoper/public_html snicoper:snicoper /home/snicoper/public_html vim /etc/nginx/conf.d/workspace.local.conf server { listen 80; server_name www.workspace.local; access_log /var/log/nginx/workspace-access.log; error_log /var/log/nginx/workspace-error.log; root /home/snicoper/public_html; location / { index index.html index.htm index.php; } location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ { access_log off; log_not_found off; expires 360d; } # Si quiero que se vean los archivos y directorios cambiar a on autoindex on; location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; 3.5. Nginx 57 Apuntes Informatica Documentation, Publicación 1.0.0 fastcgi_param SCRIPT_FILENAME /home/snicoper/public_html$fastcgi_script_name; } } systemctl restart nginx.service systemctl restart php-fpm.service Ver Reglas SELinux 3.6 PHP Todo esto puede estar muy desactualizado. Categorias: 3.6.1 PHP Composer curl -s https://getcomposer.org/installer | php sudo mv composer.phar /usr/local/bin/composer # Para actualizar composer composer self-update 3.6.2 Instalación Laravel Fuentes http://laravel.com/docs/quick#installation Fedora yum install -y php-curl Centos 7, si se ha instalado php 5.5 yum install --enablerepo=remi,remi-php55 php-curl Ubuntu sudo apt-get install php5-curl Composer o Archivo Phar Creo que composer lo tiene mas actualizado composer self-update, con archivo Phar, has de estar descargándolo a “mano” cada que se quiera actualizar. 58 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Composer PHP Composer composer create-project laravel/laravel your-project-name --prefer-dist Phar Como root wget http://laravel.com/laravel.phar chmod +x laravel.phar mv laravel.phar /usr/local/bin/laravel laravel --version 3.6.3 Instalación MariaDB Instalación MariaDB Ubuntu sudo apt-get install php5-mysqlnd sudo apt-get install phpmyadmin Fedora yum install php-mysqlnd yum install phpmyadmin 3.6.4 Instalación PHP Ubuntu Apache y Nginx sudo apt-get install -y php5 php5-cli php5-gd php5-xsl php5-json php5-mcrypt Nota: Si se instala Nginx, desactivar uno de los dos, ver carpeta de Ubuntu para desactivar servicios. Importante: Crear enlace cuando este creado el archivo de Ubuntu para desactivar servicios. Apache 3.6. PHP 59 Apuntes Informatica Documentation, Publicación 1.0.0 sudo apt-get install libapache2-mod-php5 Nginx sudo apt-get install php5-fpm sudo php5enmod mcrypt PHP.ini Apache sudo cp /usr/share/php5/php.ini-development /etc/php5/apache2/php.ini sudo vim /etc/php5/apache2/php.ini Nginx sudo cp /usr/share/php5/php.ini-development /etc/php5/fpm/php.ini sudo vim /etc/php5/fpm/php.ini Nginx y Apache Nota: Se puede omitir, es el cli sudo cp /usr/share/php5/php.ini-production.cli /etc/php5/cli/php.ini sudo vim /etc/php5/cli/php.ini Modificar php.ini y cli/php.ini expose_php = Off short_open_tag Off timezone Europe/Madrid Configuracion php-opcache En la linea 1877 mas o menos: opcache.enable=1 opcache.enable_cli=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60 opcache.fast_shutdown=1 Apache sudo service apache2 restart 60 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Nginx sudo service nginx restart sudo service php5-fpm restart Fedora Centos Nota: Para php 5.5 en Centos usar: yum –enablerepo=remi,remi-php55, yo lo omito por que todo lo demás es igual en Fedora que en Centos. yum install -y php php-gd php-pdo php-mcrypt php-cli php-opcache Para ver lista de paquetes php-* yum search php- Fedora cp /usr/share/doc/php-common/php.ini-development /etc/php.ini Centos cp /usr/share/doc/php-common-5.5.14/php.ini-development /etc/php.ini Fedora y Centos yum install php-fpm -y vim /etc/php-fpm.d/www.conf # Linea 39, cambiar puerto a 9090 listen = 127.0.0.1:9090 systemctl start php-fpm.service systemctl enable php-fpm.service Si se quiere cambiar el puerto de php-fpm (No cambiar) vim /etc/php-fpm.d/www.conf # Linea 39, cambiar puerto a 9090 listen = 127.0.0.1:9090 PHP.ini vim /etc/php.ini Buscar y editar 3.6. PHP 61 Apuntes Informatica Documentation, Publicación 1.0.0 timezone Europe/Madrid php_expose = off short_open_tags = off Configuracion de php-opcache En la linea 1872 (Fedora) 1836 (Centos), debajo de [opcache], añadir opcache.enable=1 opcache.enable_cli=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60 opcache.fast_shutdown=1 3.6.5 PHP Memcahed Instalación de Memcached Fedora yum -y install php-pecl-memcached Ubuntu sudo apt-get install php5-memcached 3.6.6 PHP MongoDB Instalación MongoDb Fedora yum install php-pecl-mongo Ubuntu sudo apt-get install php5-mongo 62 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.6.7 Pear Fedora yum install -y php-pear Ubuntu sudo apt-get install php5-pear 3.6.8 PHP PostgreSQL Ubuntu sudo apt-get install -y php5-pgsql # Opcional sudo apt-get install -y phppgadmin Configurar phppgadmin sudo vim /usr/share/phppgadmin/conf/config.inc.php Buscar $conf[’extra_login_security’] y poner el valor a false $conf['extra_login_security'] = false; Fedora yum install -y php-pgsql # Opcional yum install -y phpPgAdmin Centos Para PHP 5.5 yum install -y php-pgsql --enablerepo=remi,remi-php55 # Opcional yum install -y phpPgAdmin --enablerepo=remi,remi-php55 Configuracon phpPgAdmin, Fedora y Centos cp /usr/share/phpPgAdmin/conf/config.inc.php-dist /usr/share/phpPgAdmin/conf/config.inc.php vim /usr/share/phpPgAdmin/conf/config.inc.php Buscar $conf[’extra_login_security’] y poner el valor a false 3.6. PHP 63 Apuntes Informatica Documentation, Publicación 1.0.0 $conf['extra_login_security'] = false; 3.6.9 PHPDocumentor 2 PHAR Como root wget http://phpdoc.org/phpDocumentor.phar chmod +x phpDocumentor.phar mv phpDocumentor.phar /usr/local/bin/phpdoc phpdoc --version PEAR Instalar Pear pear channel-discover pear.phpdoc.org pear install phpdoc/phpDocumentor Composer Instalar PHP Composer composer require --dev phpdocumentor/phpdocumentor dev-master Después se podrá ejecutar phpDocumentor directamente desde el directorio vendor: 3.6.10 PHPUnit Como root wget https://phar.phpunit.de/phpunit.phar chmod +x phpunit.phar sudo mv phpunit.phar /usr/local/bin/phpunit phpunit --version 3.6.11 XDebug Ver Instalación PHP Ubuntu sudo apt-get install php5-xdebug sudo vim /etc/php5/mods-available/xdebug.ini 64 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 zend_extension=/usr/lib/php5/20100525/xdebug.so xdebug.remote_enable=on xdebug.remote_handler=dbgp xdebug.remote_host=localhost xdebug.remote_port=9000 xdebug.output_buffering=off Fedora dnf install php-pecl-xdebug -y Centos PHP 5 yum install --enablerepo=remi,remi-php55 php-pecl-xdebug Fedora y Centos PHP 5 vim /etc/php.d/xdebug.ini ; Enable xdebug extension module zend_extension=/usr/lib64/php/modules/xdebug.so xdebug.remote_enable=on xdebug.remote_handler=dbgp xdebug.remote_host=localhost xdebug.remote_port=9090 xdebug.output_buffering=off 3.7 PostgreSQL Categorias: 3.7.1 Instalación de Postgis Fuentes http://postgis.net/docs/postgis_installation.html dnf -y install postgis Es necesaio habilitar cada base de datos psql psql psql psql -U -U -U -U postgres postgres postgres postgres 3.7. PostgreSQL -c -d -d -d "CREATE DATABASE nombre_database WITH OWNER nombre_usuario;" nombre_database -c "CREATE EXTENSION postgis;" nombre_database -c "CREATE EXTENSION postgis_topology;" nombre_database -c "SELECT postgis_version();" 65 Apuntes Informatica Documentation, Publicación 1.0.0 3.7.2 Instalación de PostgreSQL Fuentes https://help.ubuntu.com/community/PostgreSQL Fedora y Centos Instalación dnf install -y postgresql postgresql-server postgresql-devel # Opcional dnf install -y pgadmin3 # Centos # postgresql-setup initdb # Fedora postgresql-setup --initdb --unit postgresql systemctl enable postgresql.service systemctl start postgresql.service Establecer contraseña de postgres su - postgres psql \password postgres CREATE USER snicoper WITH PASSWORD '123456' NOCREATEDB NOCREATEUSER; CREATE DATABASE practicas WITH OWNER snicoper; \q exit Configuración vim /var/lib/pgsql/data/postgresql.conf # linea 59 listen_addresses = 'localhost' # linea 63 descomentar port = 5432 vim /var/lib/pgsql/data/pg_hba.conf Remplazar toda la parte siguiente al final del archivo # TYPE DATABASE USER ADDRESS # "local" is for Unix domain socket connections only local all all # IPv4 local connections: host all all 127.0.0.1/32 # IPv6 local connections: host all all ::1/128 66 METHOD md5 md5 md5 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 systemctl restart postgresql.service Ver Reglas SELinux Ubuntu Instalación sudo apt install -y postgresql postgresql-contrib libpq-dev # Opcional sudo apt install -y pgAdmin3 Establecer contraseña de postgres su - postgres psql \password postgres CREATE USER snicoper WITH PASSWORD '123456' NOCREATEDB NOCREATEUSER; CREATE DATABASE practicas WITH OWNER snicoper; \q exit Configuración PostgreSQL sudo vim /etc/postgresql/9.5/main/postgresql.conf # Descomentar, linea 59 listen_addresses = 'localhost' # Descomentar, linea 89 password_encryption = on sudo vim /etc/postgresql/9.5/main/pg_hba.conf # "local" is for Unix domain socket connections only local all all md5 sudo service postgresql restart 3.8 Python Categorias: 3.8.1 Apuntes PIP psycopg2 dnf install postgresql-devel (virtualenv) pip install psycopg2 3.8. Python 67 Apuntes Informatica Documentation, Publicación 1.0.0 Pillow Fuente http://pillow.readthedocs.org/en/latest/installation.html dnf install -y \ libtiff-devel \ libjpeg-devel \ zlib-devel \ freetype-devel \ lcms2-devel \ libwebp-devel \ tcl-devel \ tk-devel pygraphviz Útil para generar gráficos de los modelos con django-extensions dnf install -y graphviz graphviz-devel (virtualenv) pip install pygraphviz 3.8.2 Compilar Python 3.5.2 en Centos 7 Compilación sudo yum install \ zlib-devel \ bzip2-devel \ openssl-devel \ ncurses-devel \ sqlite-devel \ readline-devel \ tk-devel \ gdbm-devel \ db4-devel \ libpcap-devel \ xz-devel sudo echo "/usr/local/lib" >> /etc/ld.so.conf wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz tar -zxvf Python-3.5.2.tgz cd Python-3.5.2 ./configure --prefix=/usr/local --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib" make sudo make altinstall Usar pip con pip3.5 68 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Virtualenvwrapper su pip3.5 install virtualenvwrapper exit Como usuario: mkdir ~/.virtualenvs Añadir a ~/.bashrc vim ~/.bashrc export VIRTUALENVWRAPPER_PYTHON=/usr/local/bin/python3.5 export WORKON_HOME=$HOME/.virtualenvs source /usr/local/bin/virtualenvwrapper.sh # Guardar y salir source ~/.bashrc Comandos mkvirtualenv // Crea un nuevo virtualenv rmvirtualenv // Elimina un virtualenv existente workon // Cambia el actual virtualenv deactivate // Desactivar virtualenv lsvirtualenv // Listar virtualenvs 3.8.3 Instalación Python en Fedora Python3 su dnf install -y python3-setuptools python3-devel redhat-rpm-config Virtualenvwrapper pip3 install virtualenvwrapper Editar .bashrc vim ~/.bashrc # Virtualenvwrapper export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 export WORKON_HOME=$HOME/.virtualenvs source /usr/bin/virtualenvwrapper.sh # Guardar y salir source ~/.bashrc mkvirtualenv default 3.8. Python 69 Apuntes Informatica Documentation, Publicación 1.0.0 (default) pip install -U \ autopep8 \ Django \ flake8 \ isort \ pydocstyle \ Sphinx \ sphinx-autobuild \ sphinx-rtd-theme Comandos mkvirtualenv // Crea un nuevo virtualenv rmvirtualenv // Elimina un virtualenv existente workon // Cambia el actual virtualenv deactivate // Desactivar virtualenv lsvirtualenv // Listar virtualenvs Python 3.4 en Centos 7 ... code-block:: bash yum install python34 python34-setuptools python34-devel redhat-rpm-config curl https://bootstrap.pypa.io/get-pip.py | python3.4 3.8.4 Instalacion Python en Ubuntu Python3 sudo apt install -y python3 python3-dev python3-setuptools python3-pip Virtualenvwrapper sudo pip3 install virtualenvwrapper mkdir ~/.virtualenvs Editar .bashrc vim ~/.bashrc Añadir export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 export WORKON_HOME=$HOME/.virtualenvs source /usr/local/bin/virtualenvwrapper.sh Comandos mkvirtualenv // Crea un nuevo virtualenv rmvirtualenv // Elimina un virtualenv existente workon // Cambia el actual virtualenv deactivate // Desactivar virtualenv 70 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 lsvirtualenv // Listar virtualenvs 3.8.5 Actualizar todos los paquetes de Pip pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs pip install -U Tambien se puede crear un archivo pip-upgrade-all vim pip-upgrade-all #!/bin/bash # Actualiza todos los paquetes pip de un entorno virtual. # Primero genera un archivo en el directorio actual, con los # paquetes. # Después actualiza todos los paquetes a la ultima versión. env_name=$(basename "$VIRTUAL_ENV") if [ -n "$env_name" ] then path_backup="${PWD}/pip-${env_name}-backup.txt" # Creara un backup con las versiones actuales, por si pasa algo. pip freeze > $path_backup pip freeze --local | grep -v '^\-e' | cut -d = -f 1 else echo "No estas en un entorno virtual" fi | xargs pip install -U read -p "Eliminar ${path_backup}(y/[N]) " yn if [ "$yn" == "y" -o "$yn" == "Y" ] then rm -f $path_backup fi Dar permisos de ejecución chmod +x pip-upgrade-all y moverlo a /usr/bin/ sudo mv pip-upgrade-all /usr/bin/pip-upgrade-all Ahora desde cualquier entorno virtual. (myenv) pip-upgrade-all 3.8.6 PYTHONPATH Editar vimrc vim ~/.vimrc Añadir 3.8. Python 71 Apuntes Informatica Documentation, Publicación 1.0.0 PYTHONPATH="/home/snicoper/.virtualenvs/default/lib/python3.4/site-packages/":"${PYTHONPATH}" export PYTHONPATH Donde /home/snicoper/.virtualenvs/default/lib/python3.4/site-packages/ sustituirlo por un directorio. 3.9 Redis Categorias: 3.9.1 Instalar Redis Fuentes http://redis.io/ Fedora dnf install -y redis systemctl start redis.service systemctl enable redis.service Ubuntu sudo apt-get install redis-server Backup del archivo de configuración cp /etc/redis/redis.conf /etc/redis/redis.conf.default 3.10 Ruby Categorias: 3.10.1 Instalación Ruby Instalación Dependencias para Ruby, si se omiten, cuando se instale Ruby desde rvm, pedirá instalarlas. Prerrequisitos 72 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 # Fedora sudo dnf install gcc-c++ patch readline readline-devel zlib zlib-devel \ libyaml-devel libffi-devel openssl-devel make \ bzip2 autoconf automake libtool bison sqlite-devel # Ubuntu sudo apt-get install gawk libreadline6-dev libyaml-dev libsqlite3-dev sqlite3 \ autoconf libgdbm-dev libncurses5-dev automake libtool bison libffi-dev sudo apt-get install nodejs rvm gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 \curl -sSL https://get.rvm.io | bash source ~/.profile Ruby Instalar Ruby Tarda su tiempo!! rvm install ruby ruby -v Rails Instalar Rails gem install rails rails -v SASS gem install sass sass -v 3.11 Ubuntu Categorias: 3.11.1 Bind Fuentes http://www.belinuxmyfriend.com/2007/07/ip-estatica-en-ubuntu-manualmente.html http://www.server-world.info/en/note?os=Ubuntu_13.04&p=dns&f=1 3.11. Ubuntu 73 Apuntes Informatica Documentation, Publicación 1.0.0 http://lani78.com/2012/07/22/setting-up-a-dns-for-the-local-network-on-the-ubuntu-12-04-precise-pangolinserver/ http://docs.fedoraproject.org/en-US/Fedora/20/html/Networking_Guide/index.html Instalacion sudo apt install bind9 bind9utils Configuración Red sudo vim /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.1.10 netmask 255.255.255.0 gateway 192.168.1.1 network 192.168.1.0 dns-nameservers 192.168.1.10 8.8.4.4 8.8.8.8 dns-search ns1.workspace.local dns-domain workspace.local Configuracion Bind sudo vim /etc/bind/named.conf.options # En forwarders forwarders { 89.36.215.212; 8.8.8.8; 8.8.4.4; }; auth-nxdomain no; # conform to RFC1035 #listen-on-v6 { any; }; listen-on port 53 { 127.0.0.1; 89.36.215.212; }; allow-query { any; }; allow-transfer { any; }; sudo vim /etc/bind/named.conf.local zone "ofervivienda.com" IN { type master; file "/etc/bind/db.ofervivienda"; }; zone "36.215.89.in-addr.arpa" IN { type master; file "/etc/bind/db.89.36.215.212"; }; sudo vim /etc/bind/db.ofervivienda 74 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 $TTL 86400 @ IN ; SOA ofervivienda.com. 2013042201 43200 3600 3600000 2592000 ) hostmaster.ofervivienda.com. ( ; Serial ; Refresh ; Retry ; Expire ; Minimum Define the nameservers and the mail servers mail ns1 www IN NS ns1.ofervivienda.com. IN A 89.36.215.212 IN MX 10 mail.ofervivienda.com. IN IN IN A A CNAME 89.36.215.212 89.36.215.212 ofervivienda.com. sudo vim /etc/bind/db.89.36.215.212 $TTL 86400 @ IN SOA @ ofervivienda.com. 2013042201 43200 3600 3600000 2592000 ) hostmaster.ofervivienda.com. ( ; Serial ; Refresh ; Retry ; Expire ; Minimum IN NS ns1.ofervivienda.com. IN PTR ofervivienda.com. IN PTR ns1.ofervivienda.com. 212 systemctl start bind9 systemctl enable bind9 ufw allow 53 3.11.2 Crear certificado SSL Pongo el nombre de ofervivienda para el servidor principal, cambiar si es otro servidor sudo -s cd /etc/ssl/private openssl genrsa -des3 -out ofervivienda.key 2048 openssl req -new -days 3650 -key ofervivienda.key -out ofervivienda.csr Country Name (2 letter code) [XX]:es State or Province Name (full name) []:Spain Locality Name (eg, city) [Default City]:Barcelona Organization Name (eg, company) [Default Company Ltd]:snicoper 3.11. Ubuntu 75 Apuntes Informatica Documentation, Publicación 1.0.0 Organizational Unit Name (eg, section) []:nombre_org Common Name (eg, your name or your server's hostname) []:ofervivienda.workspace.local Email Address []:snicoper@gmail.com A challenge password []: (Intro) An optional company name []: (Intro) openssl x509 -in ofervivienda.csr -out ofervivienda.crt -req -signkey ofervivienda.key -days 3650 chmod 400 ofervivienda.* 3.11.3 Post instalacion Ubuntu Probado en Ubuntu 14.04 Si se usa calligra, eliminar libreoffice antes de actualizar. sudo apt remove --purge libreoffice* Actualizar. sudo apt update && sudo apt dist-upgrade Si es una instalación de VirtualBox. sudo apt install virtualbox-guest-dkms Instalar Vim. sudo apt -y install vim Cambiar editor. sudo update-alternatives --config editor Programas basicos. sudo apt install -y \ build-essential \ git \ git-cola \ exuberant-ctags \ curl \ wget \ ssh \ unrar \ htop \ nmap \ tree \ python-pygments # JDK y JRE sudo apt install -y \ openjdk-7-jre \ openjdk-7-jdk Diccionario español. 76 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 sudo apt install aspell-es myspell-es -y KDE Si se configura Akonadi con SQLite o PostgreSQL. Cambiar en Menú > buscar Akonadi Server Configuration. sudo apt install akonadi-backend-sqlite sudo apt install akonadi-backend-postgresql Muon. sudo apt -y install muon Calligra. sudo apt install calligra -y kdiff3. sudo apt install kdiff3-qt -y Utilidades KDE. sudo apt install kgpg kleopatra kcolorchooser -y Para visualizar las miniaturas en Dolphin de los .pdf. sudo apt install kdegraphics-thumbnailers -y Eliminar. sudo apt remove --purge kget amarok -y Opcionales. sudo apt install kdeplasma-addons -y Transmision. sudo apt install transmission-qt -y qBittorent. sudo apt install qbittorrent -y GNOME Eliminar en Ubuntu Unity Amazon. sudo apt remove --purge unity-webapps-common Synaptic. sudo apt install synaptic 3.11. Ubuntu 77 Apuntes Informatica Documentation, Publicación 1.0.0 Open terminal here. sudo apt install nautilus-open-terminal Meld. sudo apt install meld -y gpick. sudo apt install gpick -y libreoffice. sudo apt install libreoffice RabbitVCS. sudo add-apt-repository ppa:rabbitvcs/ppa sudo apt update sudo apt install rabbitvcs-nautilus3 rabbitvcs-cli Menus have icons y buttons have icons gsettings set org.gnome.desktop.interface menus-have-icons true gsettings set org.gnome.desktop.interface buttons-have-icons true KDE/GNOME Umbrello. sudo apt install -y umbrello Gui SQLite. sudo apt install -y sqlitebrowser Thunderbird. sudo apt install thunderbird Chromium. sudo apt install chromium-browser -y Vlc. sudo apt install vlc Inskape y gimp. sudo apt install gimp inkscape Filezilla. sudo apt install filezilla Kdevelop. 78 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 sudo apt install kdevelop cmake kdevelop python. sudo apt install kdev-python pep8 qtcreator. sudo apt -y install qtcreator No mostrar la opción de cuenta de invitado al hacer login. sudo sh -c 'printf "[SeatDefaults]\nallow-guest=false\n" >/usr/share/lightdm/lightdm.conf.d/50-no-gue 3.11.4 Post instalacion Ubuntu Server Crear usuario y añadir a wheel adduser snicoper passwd snicoper sudo adduser snicoper sudo hostname hostnamectl --static set-hostname fqdn.host.name Timezone timedatectl set-timezone Europe/Madrid Cambiar Keyboard Layout (keymap) locale-gen es_ES.UTF-8 localectl list-locales | grep es Para cambiar a es localectl set-keymap es_ES.utf8 Instalar Vim. sudo apt -y install vim Cambiar editor. sudo update-alternatives --config editor Recordar ultima posicion. 3.11. Ubuntu 79 Apuntes Informatica Documentation, Publicación 1.0.0 vim /etc/vim/vimrc # Descomentar lineas, 29, 30 y 31 " Uncomment the following to have Vim jump to the last position when " reopening a file if has("autocmd") au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif endif Habiliar ufw (firewall) sudo ufw allow 22 sudo ufw enable Actualizar Cambiar a servers francia. sudo vim /etc/apt/sources.list Actualizar sudo apt update && sudo apt dist-upgrade Pquetes basicos sudo apt install -y \ build-essential \ git \ curl \ wget \ ssh \ htop \ nmap \ tree 3.11.5 Postfix Instalación sudo apt-get install postfix sasl2-bin dovecot-common dovecot-pop3d dovecot-imapd Postfix Durante la instalación cuando pregunte por el certificado SSL, decir que no. Después darle a <ok> Por ultimo, No configuration 80 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 sudo cp /usr/lib/postfix/main.cf /etc/postfix/main.cf sudo vim /etc/postfix/main.cf # line 59: uncomment mail_owner = postfix # line 76: uncomment and specify hostname myhostname = mail.workspace.local # line 83: uncomment and specify domain name mydomain = workspace.local # line 104: uncomment myorigin = $mydomain # line 118: uncomment inet_interfaces = all # line 166: uncomment mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain # line 209: uncomment local_recipient_maps = unix:passwd.byname $alias_maps # line 268: uncomment and specify your LAN mynetworks = 192.168.0.0/24, 127.0.0.0/16 # line 388: uncomment alias_maps = hash:/etc/aliases # line 399: uncomment alias_database = hash:/etc/aliases # line 421: uncomment (use Maildir) home_mailbox = Maildir/ # line 531: uncomment header_checks = regexp:/etc/postfix/header_checks # add: mail body checking body_checks = regexp:/etc/postfix/body_checks # line 557: make it comment and add below # smtpd_banner = $myhostname ESMTP $mail_name (@@DISTRO@@) smtpd_banner = $myhostname ESMTP # line 631: add sendmail_path = /usr/sbin/postfix # line 636: add newaliases_path = /usr/bin/newaliases # line 641: add mailq_path = /usr/bin/mail # line 647: add setgid_group = postdrop 3.11. Ubuntu 81 Apuntes Informatica Documentation, Publicación 1.0.0 # line 651: make it comment # html_directory = # line 655: make it comment # manpage_directory = # line 660: make it comment # sample_directory # line 664: make it comment # readme_directory = # add at the lasdt line: # limit an email size 10M message_size_limit = 10485760 # limit mailbox 1G mailbox_size_limit = 1073741824 # for SMTP-Auth settings smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = $myhostname smtpd_client_restrictions = permit_mynetworks,reject_unknown_client,permit smtpd_recipient_restrictions = permit_mynetworks,permit_auth_destination,permit_sasl_authenticated,re sudo vim /etc/postfix/header_checks # add at the head ( reject if email address is empty ) /^From:.*<#.*@.*>/ REJECT /^Return-Path:.*<#.*@.*>/ REJECT sudo vim /etc/postfix/body_checks # reject if includes 'example.com' in mail body /^(|[^>].*)example.com/ REJECT sudo vim /etc/aliases # Añadir root: snicoper@mail.workspace.local sudo newaliases sudo service postfix restart Dovecot sudo vim /etc/dovecot/conf.d/10-auth.conf # line 10: uncomment and change ( allow plain text auth ) disable_plaintext_auth = no # line 100: add auth_mechanisms = plain login 82 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 sudo vim /etc/dovecot/conf.d/10-mail.conf # line 30: uncomment and add mail_location = maildir:~/Maildir sudo vim /etc/dovecot/conf.d/10-master.conf # line 95: uncomment and add # Postfix smtp-auth unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix # add group = postfix # add } sudo service dovecot restart SSL Ver Crear certificado SSL sudo vim /etc/postfix/main.cf Nota: Usar lxmaq1.crt y lxmaq1.key con los mismos nombres que se hayan creado en Crear certificado SSL # add at the last line # SSL smtpd_use_tls = yes smtpd_tls_cert_file = /etc/ssl/private/lxmaq1.crt smtpd_tls_key_file = /etc/ssl/private/lxmaq1.key smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache sudo vim /etc/postfix/master.cf # line 28-30: uncomment smtps inet n -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes - - - smtpd sudo vim /etc/dovecot/conf.d/10-ssl.conf # line 6: uncomment ssl = yes # line 12,13: uncomment and specify certificate ssl_cert = </etc/ssl/private/lxmaq1.crt ssl_key = </etc/ssl/private/lxmaq1.key sudo service postfix restart sudo service dovecot restart 3.11. Ubuntu 83 Apuntes Informatica Documentation, Publicación 1.0.0 3.11.6 ufw Fuentes https://help.ubuntu.com/14.04/serverguide/firewall.html Estos son comandos muy básicos, para mas info en Fuentes Habiliar sudo ufw enable Para ver las reglas actuales sudo ufw status numbered Para abrir un puerto sudo ufw allow 22 Cerrar un puerto sudo ufw deny 22 Para eliminar una regla sudo ufw delete deny 22 sudo ufw delete allow 22 sudo ufw delete allow proto tcp from 192.168.1.0/24 to any port 22 Es insertar lo mismo pero con delete después de ‘sudo ufw delete (comando que se añadió)’ sudo ufw allow proto tcp from 192.168.1.2 to any port 22 sudo ufw allow proto tcp from 192.168.1.0/24 to any port 22 Abrir todo el trafico la red local sudo ufw allow from 192.168.1.0/24 Contents: 3.12 Añadir carpetas al PATH Editar ~/.bashrc vim ~/.bashrc Añadir al final PATH="$PATH:/data/myscripts" export PATH 84 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.13 Añadir programas al menu Nota: Todos los pongo en opt Prácticamente todos son iguales, solo cambian las rutas, pero las pongo separadas para ir mas rápido si algún día tengo que instalar alguno. 3.13.1 Sublime 3 Descomprimir como usuario su mv sublime_text_3 /opt/sublime_text_3 chmod +x /opt/sublime_text_3/sublime_text ln -s /opt/sublime_text_3/sublime_text /usr/local/bin/subl vim /usr/share/applications/sublime.desktop [Desktop Entry] Encoding=UTF-8 Name=Sublime Text 3 Comment=Sublime Text Editor Exec=subl %U Icon=/home/snicoper/.local/share/icons/Paper/48x48/apps/sublime-text.png #Icon=/opt/sublime_text_3/Icon/48x48/sublime-text.png Terminal=false Type=Application Categories=GNOME;Application;Development; StartupNotify=true 3.13.2 Visual Studio Code Descomprimir como usuario su mv VSCode-linux-x64 /opt/vscode chmod +x /opt/vscode/Code ln -s /opt/vscode/Code /usr/local/bin/vscode vim /usr/share/applications/vscode.desktop [Desktop Entry] Encoding=UTF-8 Name=Visual Studio Code Comment=Editor for C# and ASP.NET Exec=vscode %U Icon=/opt/vscode/resources/app/resources/linux/code.png Terminal=false Type=Application Categories=GNOME;Application;Development; StartupNotify=true 3.13. Añadir programas al menu 85 Apuntes Informatica Documentation, Publicación 1.0.0 3.13.3 PyCharm su # Si no existe /opt/jetbrains mkdir /opt/jetbrains gzip -d pycharm-professional-2016.1.4.tar.gz tar -xvf pycharm-professional-2016.1.4.tar mv pycharm-2016.1.4/ /opt/jetbrains/pycharm chmod +x /opt/jetbrains/pycharm/bin/pycharm.sh ln -s /opt/jetbrains/pycharm/bin/pycharm.sh /usr/local/bin/pycharm vim /usr/share/applications/pycharm.desktop [Desktop Entry] Encoding=UTF-8 Name=PyCharm Comment=IDE for Python Exec=pycharm %U Icon=/opt/jetbrains/pycharm/bin/pycharm.png Terminal=false Type=Application Categories=GNOME;Application;Development; StartupNotify=true 3.13.4 WebStrom su # Si no existe /opt/jetbrains mkdir /opt/jetbrains gzip -d WebStorm-11.0.1.tar.gz tar -xvf WebStorm-11.0.1.tar mv WebStorm-143.382.36/ /opt/jetbrains/webstorm chmod +x /opt/jetbrains/webstorm/bin/webstorm.sh ln -s /opt/jetbrains/webstorm/bin/webstorm.sh /usr/local/bin/webstorm vim /usr/share/applications/webstorm.desktop [Desktop Entry] Encoding=UTF-8 Name=webstorm Comment=IDE for Web Exec=webstorm %U Icon=/opt/jetbrains/webstorm/bin/webstorm.svg Terminal=false Type=Application Categories=GNOME;Application;Development; StartupNotify=true 3.13.5 Discord sudo dnf install libXScrnSaver De momento esta en una fase muy temprana 86 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 Descargar y descomprimir de GitHub su mv DiscordCanary /opt/discord chmod +x /opt/discord/DiscordCanary ln -s /opt/discord/DiscordCanary /usr/local/bin/discord vim /usr/share/applications/discord.desktop [Desktop Entry] Encoding=UTF-8 Name=Discord Comment=Chat Exec=discord %U Icon=/opt/discord/discord.png Terminal=false Type=Application StartupNotify=true 3.13.6 Telegram Para mostrar icono en la bandeja dnf install libappindicator-gtk3 # Alt+F2 -> r (Enter) su tar Jxvf tsetup.0.9.40.tar.xz chmod +x Telegram/Telegram mv Telegram /opt/Telegram ln -s /opt/Telegram/Telegram /usr/local/bin/telegram vim /usr/share/applications/telegram.desktop [Desktop Entry] Encoding=UTF-8 Name=Telegram Comment=Chat Exec=telegram %U Icon=/home/snicoper/.local/share/icons/telegram.png Terminal=false Type=Application StartupNotify=true 3.14 Comando Cat con texto coloreado Desde los repositorios # Fedora/Centos yum install python-pygments # Ubuntu apt-get install python-pygments 3.14. Comando Cat con texto coloreado 87 Apuntes Informatica Documentation, Publicación 1.0.0 Con Pip ver Instalacion Python en Ubuntu # Python 2 pip install Pygments # Python 3 pip3 install Pygments Editar ~/.bashrc y añadir alias alias ccat='pygmentize -g' 3.15 Chromium español linux 3.15.1 Forma rapida vim /usr/bin/chromium-browser Añadir al inicio, despues de #!/bin/bash export LANGUAGE=es 3.16 Comando dd Grabar de una .iso a un cd/pen sudo dd if=Fedora-14-x86_64-Live-KDE.iso of=/dev/sdb Para crear una .iso de un cd/dvd dd if=/dev/lectora of=/home/usuario/Escritorio/dvd.iso 3.17 Comando find Comando find, directorio ./, patron -name, archivo o directorio -type f|d, comando a ejecutar -exec comando {} \; Algunos ejemplos Dar permisos 777 a todos los archivos recursivamente desde la posición actual. find ./ -name '*.php' -type f -exec chmod 777 {} \; Eliminar recursivamente carpetas con X nombre desde la posición actual. find ./ -name '*.php' -type f -exec rm -f {} \; Cambiar de permisos recursivamente desde la posición actual. find ./ -type f -exec dos2unix {} \; 88 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.18 Comando setfacl Para poder compartir permisos con 2 usuarios distintos, usar setfacl Por ejemplo, en la carpeta /home/snicoper/public_html/example.com/uploads sudo setfacl -R -m u:snicoper:rwx -m u:apache:rwx ~/public_html/example.com/uploads sudo setfacl -dR -m u:snicoper:rwx -m u:apache:rwx ~/public_html/example.com/uploads De esta manera, tanto apache como snicoper, tendrán permisos rwx 3.19 Comprimir descomprimir desde consola Ficheros tar # Empaquetar: tar -cvf archivo.tar /dir/a/comprimir/ # Desempaquetar: tar -xvf archivo.tar # Ver contenido: tar -tf archivo.tar Ficheros gz #Comprimir: gzip -9 fichero # Descomprimir: gzip -d fichero.gz Ficheros bz2 # Comprimir: bzip fichero # Descomprimir: bzip2 -d fichero.bz2 gzip ó bzip2 sólo comprimen ficheros [no directorios, para eso existe tar]. Para comprimir y archivar al mismo tiempo hay que combinar el tar y el gzip o el bzip2 de la siguiente manera: Ficheros tar.gz # Comprimir: tar -czfv archivo.tar.gz ficheros # Descomprimir: tar -xzvf archivo.tar.gz # Ver contenido: tar -tzf archivo.tar.gz Ficheros tar.bz2 # Comprimir: tar -c ficheros | bzip2 > archivo.tar.bz2 3.18. Comando setfacl 89 Apuntes Informatica Documentation, Publicación 1.0.0 # Descomprimir: bzip2 -dc archivo.tar.bz2 | tar -xv # Ver contenido: bzip2 -dc archivo.tar.bz2 | tar -t Ficheros zip # Comprimir: zip archivo.zip ficheros # Descomprimir: unzip archivo.zip # Ver contenido: unzip -v archivo.zip Ficheros lha # Comprimir: lha -a archivo.lha ficheros # Descomprimir: lha -x archivo.lha # Ver contenido: lha -v archivo.lha # Ver contenido: lha -l archivo.lha Ficheros arj # Comprimir: arj a archivo.arj ficheros # Descomprimir: unarj archivo.arj # Descomprimir: arj -x archivo.arj # Ver contenido: arj -v archivo.arj # Ver contenido: arj -l archivo.arj Ficheros zoo # Comprimir: zoo a archivo.zoo ficheros # Descomprimir: zoo -x archivo.zoo # Ver contenido: zoo -L archivo.zoo 90 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 # Ver contenido: zoo -v archivo.zoo Ficheros rar # Comprimir: rar -a archivo.rar ficheros # Descomprimir: rar -x archivo.rar # Ver contenido: rar -l archivo.rar # Ver contenido: rar -v archivo.rar 3.20 Configurar mutt Fuentes http://www.elho.net/mutt/maildir/ # Fedora vim /etc/Muttrc # Linea 1108 set folder="~/Maildir" # Linea 2074 set mask="!^\\.[^.]" # Linea 2086 set mbox="~/Maildir" # Linea 2099 set mbox_type=Maildir # Linea 3130 set postponed="+.Drafts" # Linea 3395 set record="+.Sent" # Linea 4378 set spoolfile="~/Maildir" Para entrar al correo, simplemente mutt 3.21 Comandos Utiles 3.21.1 Fuentes http://www.infognu.com.ar/2013/05/400-comandos-para-gnulinux-que-deberias_3118.html 3.20. Configurar mutt 91 Apuntes Informatica Documentation, Publicación 1.0.0 3.21.2 Información del sistema arch → mostrar la arquitectura de la máquina (1). uname -m → mostrar la arquitectura de la máquina (2). uname -r → mostrar la versión del kernel usado. uname -a → mostrar la información completa. cat /etc/issue → mostrar el nombre de la distribución dmidecode -q → mostrar los componentes (hardware) del sistema. hdparm -i /dev/hda → mostrar las características de un disco duro. hdparm -tT /dev/sda → realizar prueba de lectura en un disco duro. cat /proc/cpuinfo → mostrar información de la CPU. cat /proc/interrupts → mostrar las interrupciones. cat /proc/meminfo → verificar el uso de memoria. cat /proc/swaps → mostrar ficheros swap. cat /proc/version → mostrar la versión del kernel. cat /proc/net/dev → mostrar adaptadores de red y estadísticas. cat /proc/mounts → mostrar el sistema de ficheros montado. lspci -tv → mostrar los dispositivos PCI. lsusb -tv → mostrar los dispositivos USB. lshw → listar el hardware. discover → listar el hardware. date → mostrar la fecha del sistema. cal 2011 → mostrar el almanaque de 2011. cal 07 2011 → mostrar el almanaque para el mes julio de 2011. date 041217002011.00 → colocar (declarar, ajustar) fecha y hora. clock -w → guardar los cambios de fecha en la BIOS. blkid → mostrar información (nombre, etiqueta, UUID, tipo de partición) sobre los dispositivos de bl 3.21.3 Apagar, reiniciar o cerrar sesión shutdown -h now → apagar el sistema (1). init 0 → apagar el sistema (2). telinit 0 → apagar el sistema (3). halt → apagar el sistema (4). shutdown -h hours:minutes & → apagado planificado del sistema. shutdown -c → cancelar un apagado planificado del sistema. shutdown -r now → reiniciar (1). reboot → reiniciar (2). logout → cerrar sesión. skill nombre_de_usuario → cerrar sesión (2) [Es preciso ejecutarlo con privilegios de root] exit → salir del intérprete de comandos (si solo hay uno, equivale a cerrar sesión). 3.21.4 Gestionar archivos y directorios cd → ir al directorio personal. cd /home → cambiar al directorio “/home”. cd .. → retroceder un nivel. cd ../.. → retroceder 2 niveles. cd ~user1 → ir al directorio user1. cd - → ir (regresar) al directorio anterior. pwd → mostrar el camino del directorio actual. ls → listar el contenido de un directorio. ls -F → listar el contenido de un directorio (distinguiendo los directorios con una barra) ls -l → listar el contenido de un directorio, mostrando los detalles. ls -lh → listar el contenido de un directorio, mostrando los detalles (y el tamaño en un formato “hu 92 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 ls -a → listar el contenido de un directorio, incluendo los ficheros ocultos. ls *[0-9] → listar los ficheros y carpetas que contienen números. ls -laR | less → listar recursivamente el contenido del directorio actual y todos los subdirectorios tree → mostrar los ficheros y carpetas en forma de árbol comenzando por la raíz.(1) lstree → mostrar los ficheros y carpetas en forma de árbol comenzando por la raíz.(2) mkdir dir1 → crear un directorio de nombre ‘dir1. mkdir dir1 dir2 → crear dos directorios a la vez (en la ubicación actual). mkdir -p /tmp/dir1/dir2 → crear una estructura de directorios, si no existe. rm file1 → eliminar el archivo ‘file1. rm -f file1 → eliminar el archivo ‘file1 en modo forzado. rmdir dir1 → borrar el directorio ‘dir1. rm -rf dir1 → eliminar recursivamente y en modo forzado el directorio ‘dir1 con todo lo que contenga rm -rf dir1 dir2 → borrar dos directorios con su contenido de forma recursiva. mv dir1 new_dir → renombrar o mover un fichero o carpeta (directorio). cp file1 destino/ → copiar un fichero al destino elegido. cp file1 file2 destino/ → copiar a la vez dos ficheros a un mismo directorio. cp file1 file2 → copiar file1 en file2. cp dir /* . → copiar todos los ficheros de un directorio dentro del directorio de trabajo actual. cp -a /tmp/dir1 . → copiar un directorio dentro del directorio actual de trabajo. cp -a dir1 → copiar un directorio. cp -a dir1 dir2 → copiar dos directorio al unísono. ln -s file1 lnk1 → crear un enlace simbólico al fichero o directorio. ln file1 lnk1 → crear un enlace físico al fichero o directorio. touch file1 → actualizar la fecha de modificación de file1, o crearlo si no existe. touch -t 0712250000 file1 → modificar el tiempo real (tiempo de creación) de un fichero o directorio file file1 → salida (volcado en pantalla) del tipo mime de un fichero texto. iconv -l → listas de cifrados conocidos. iconv -f fromEncoding -t toEncoding inputFile > outputFile → crea una nueva forma del fichero de ent 3.21.5 Encontrar archivos find / -name file1 → buscar fichero y directorio a partir de la raíz del sistema. find / -user user1 → buscar ficheros y directorios pertenecientes al usuario ‘user1. find /home/user1 -name \*.bin → buscar ficheros con extensión ‘. bin’ dentro del directorio ‘/ home/ find /usr/bin -type f -atime +100 → buscar ficheros binarios no usados en los últimos 100 días. find /usr/bin -type f -mtime -10 → buscar ficheros creados o cambiados dentro de los últimos 10 días find / -name \*.rpm -exec chmod 755 '{}' \; → buscar ficheros con extensión ‘.rpm’ y modificar permi find . -type f -print0 | xargs -0 chmod 644 → modificar recursivamente los permisos a todos los fich find / -xdev -name \*.rpm → Buscar ficheros con extensión ‘.rpm’ ignorando los dispositivos removibl find . -maxdepth 1 -name *.jpg -print -exec convert ”{}” -resize 80×60 “thumbs/{}” \; → agrupar fich find /tmp/dir1 -depth -regextype posix-extended -regex '.*(\s+|:+|\\+|>+|<+|”+|\*+|\?+|\|+).*' -execd locate \*.ps → encuentra ficheros con extensión ‘.ps’ ejecutados primeramente con el command ‘update whereis halt → mostrar la ubicación de un fichero binario, de ayuda o fuente. En este caso pregunta which comando → mostrar la ruta completa a un comando. 3.21.6 Montando un sistema de ficheros mount /dev/hda2 /mnt/hda2 → montar un disco llamado hda2. Verifique primero la existencia del direct umount /dev/hda2 → desmontar un disco llamado hda2. (Antes es necesario salir del punto ‘/mnt/hda2. fuser -km /mnt/hda2 → forzar el desmontaje cuando el dispositivo está ocupado. umount -n /mnt/hda2 → correr el desmontaje sin leer el fichero /etc/mtab. Útil cuando el fichero es mount /dev/fd0 /mnt/floppy → montar un disco flexible (floppy). mount /dev/cdrom /mnt/cdrom → montar un cdrom / dvdrom. mount /dev/hdc /mnt/cdrecorder → montar un cd regrabable o un dvdrom. mount /dev/hdb /mnt/cdrecorder → montar un cd regrabable / dvdrom (un dvd). 3.21. Comandos Utiles 93 Apuntes Informatica Documentation, Publicación 1.0.0 mount mount mount mount -t udf,iso9660 -o loop file.iso /mnt/cdrom → montar un fichero de imagen de un medio óptico (c -t vfat /dev/hda5 /mnt/hda5 → montar un sistema de ficheros FAT32. -t ntfs-3g /dev/hda5 /mnt/hda5 → montar un sistema de ficheros NTFS. /dev/sda1 /mnt/usbdisk → montar un usb pen-drive o una memoria (sin especificar el tipo de sis 3.21.7 Espacio en disco df -h → mostrar una lista de las particiones montadas. ls -lSr | more → mostrar el tamaño de los ficheros y directorios ordenados por tamaño. du -sh dir1 → Estimar el espacio usado por el directorio ‘dir1. du -h --max-depth=1 | sort -nr → mostrar en orden descendente el tamaño de todos los subdirectorios du -sk * | sort -rn → mostrar el tamaño de los ficheros y directorios ordenados por tamaño. rpm -q -a --qf '%10{SIZE}t%{NAME}n' | sort -k1,1n → mostrar el espacio usado por los paquetes rpm in dpkg-query -W -f='${Package}\t${Installed-Size}\n' | sort -k 2 -nr | grep -v deinstall | head -n 25 | 3.21.8 Usuarios y grupos groupadd nombre_del_grupo → crear un nuevo grupo. groupdel nombre_del_grupo → borrar un grupo. groupmod -n nuevo_nombre_del_grupo viejo_nombre_del_grupo → renombrar un grupo. useradd -c “Name Surname ” -g admin -d /home/user1 -s /bin/console user1 → Crear un nuevo usuario pe useradd user1 → crear un nuevo usuario. userdel -r user1 → borrar un usuario (‘-r’ elimina el directorio Home). usermod -c “User FTP” -g system -d /ftp/user1 -s /bin/nologin user1 → cambiar los atributos del usua usermod -aG sudoers,plugdev user1 → agregar el usuario user1 a dos grupos existentes, para increment passwd → cambiar contraseña. passwd user1 → cambiar la contraseña de un usuario (solamente por root). chage -E 2011-12-31 user1 → colocar un plazo para la contraseña del usuario. En este caso dice que l pwck → chequear la sintaxis correcta el formato de fichero de ‘/etc/passwd’ y la existencia de usuar grpck → chequear la sintaxis correcta y el formato del fichero ‘/etc/group’ y la existencia de grupo newgrp group_name → registra a un nuevo grupo para cambiar el grupo predeterminado de los ficheros c 3.21.9 Permisos en ficheros (usar “+” para colocar permisos y “-” para eliminar) ls -lh → Mostrar permisos. ls /tmp | pr -T5 -W$COLUMNS → dividir la terminal en 5 columnas. chmod ugo+rwx directory1 → colocar permisos de lectura ®, escritura (w) y ejecución(x) al propietari chmod go-rwx directory1 → quitar permiso de lectura ®, escritura (w) y (x) ejecución al grupo (g) y chown user1 file1 → cambiar el dueño de un fichero. chown -R user1 directory1 → cambiar el propietario de un directorio y de todos los ficheros y direct chgrp group1 file1 → cambiar grupo de ficheros. chown user1:group1 file1 → cambiar usuario y el grupo propietario de un fichero. find / -perm -u+s → visualizar todos los ficheros del sistema con SUID configurado. chmod u+s /bin/file1 → colocar el bit SUID en un fichero binario. El usuario que corriendo ese fiche chmod u-s /bin/file1 → deshabilitar el bit SUID en un fichero binario. chmod g+s /home/public → colocar un bit SGID en un directorio -similar al SUID pero por directorio. chmod g-s /home/public → desabilitar un bit SGID en un directorio. chmod o+t /home/public → colocar un bit STIKY en un directorio. Permite el borrado de ficheros solam chmod o-t /home/public → desabilitar un bit STIKY en un directorio. 94 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.21.10 Atributos especiales en ficheros (usar “+” para colocar permisos y “-” para eliminar) chattr chattr chattr chattr chattr chattr chattr lsattr +a +c +d +i +s +S +u → file1 → permite escribir abriendo un fichero solamente modo append. file1 → permite que un fichero sea comprimido / descomprimido automaticamente. file1 → asegura que el programa ignore borrar los ficheros durante la copia de seguridad. file1 → convierte el fichero en inmutable o invariable, por lo que no puede ser eliminado, file1 → permite que un fichero sea borrado de forma segura. file1 → asegura que un fichero sea modificado, los cambios son escritos en modo synchronou file1 → te permite recuperar el contenido de un fichero aún si este está cancelado. mostrar atributos especiales. 3.21.11 Archivos y ficheros comprimidos 7za a -mx=9 -ms=on -mhe=on -p archivocomprimido directorio1 archivo1 archivo2 → comprimir un directo 7za x archivocomprimido.7z → extraer un archivo comprimido en 7zip (7zip también permite descomprimi bunzip2 file1.bz2 → descomprime in fichero llamado ‘file1.bz2. bzip2 file1 → comprime un fichero llamado ‘file1. gunzip file1.gz → descomprime un fichero llamado ‘file1.gz’. gzip file1 → comprime un fichero llamado ‘file1. gzip -9 file1 → comprime con compresión máxima. rar a file1.rar test_file → crear un fichero rar llamado ‘file1.rar’. rar a file1.rar file1 file2 dir1 → comprimir ‘file1, ‘file2 y ‘dir1 simultáneamente. rar x file1.rar → descomprimir archivo rar. unrar x file1.rar → descomprimir archivo rar. tar -cvf archive.tar file1 → crear un tarball descomprimido. tar -cvf archive.tar file1 file2 dir1 → crear un archivo conteniendo ‘file1, ‘file2 y’dir1. tar -tf archive.tar → mostrar los contenidos de un archivo. tar -xvf archive.tar → extraer un tarball (si el archivo además está comprimido con gzip, bzip2 o xz tar -xvf archive.tar -C /tmp → extraer un tarball en /tmp. tar -cjvf archive.tar.bz2 dir1 → crear un tarball comprimido en bzip2. tar -xjvf archive.tar.bz2 → descomprimir un archivo tar comprimido en bzip2 tar -cJvf archive.tar.xz dir1 → crear un tarball comprimido en xz. XZ_OPT=-9e tar -cJvf archive.tar.xz dir1 → crear un tarball comprimido en xz (con máxima compresión) tar -xJvf archive.tar.xz → descomprimir un archivo tar comprimido en xz. tar -czvf archive.tar.gz dir1 → crear un tarball comprimido en gzip. GZIP=-9 tar -czvf archive.tar.gz dir1 → crear un tarball comprimido en gzip (con máxima compresión). tar -xzvf archive.tar.gz → descomprimir un archive tar comprimido en gzip. zip file1.zip file1 → crear un archivo comprimido en zip. zip -r file1.zip file1 file2 dir1 → comprimir, en zip, varios archivos y directorios de forma simult unzip file1.zip → descomprimir un archivo zip. 3.21.12 Paquetes rpm (Red Hat, Fedora y similares) rpm rpm rpm rpm rpm rpm rpm rpm rpm rpm rpm -ivh package.rpm → instalar un paquete rpm. -ivh --nodeeps package.rpm → instalar un paquete rpm ignorando las peticiones de dependencias. -U package.rpm → actualizar un paquete rpm sin cambiar la configuración de los ficheros. -F package.rpm → actualizar un paquete rpm solamente si este está instalado. -e package_name.rpm → eliminar un paquete rpm. -qa → mostrar todos los paquetes rpm instalados en el sistema. -qa | grep httpd → mostrar todos los paquetes rpm con el nombre “httpd”. -qi package_name → obtener información en un paquete específico instalado. -qg “System Environment/Daemons” → mostar los paquetes rpm de un grupo software. -ql package_name → mostrar lista de ficheros dados por un paquete rpm instalado. -qc package_name → mostrar lista de configuración de ficheros dados por un paquete rpm instalado 3.21. Comandos Utiles 95 Apuntes Informatica Documentation, Publicación 1.0.0 rpm -q package_name --whatrequires → mostrar lista de dependencias solicitada para un paquete rpm. rpm -q package_name --whatprovides → mostar la capacidad dada por un paquete rpm. rpm -q package_name --scripts → mostrar los scripts comenzados durante la instalación /eliminación. rpm -q package_name --changelog → mostar el historial de revisions de un paquete rpm. rpm -qf /etc/httpd/conf/httpd.conf → verificar cuál paquete rpm pertenece a un fichero dado. rpm -qp package.rpm -l → mostrar lista de ficheros dados por un paquete rpm que aún no ha sido insta rpm --import /media/cdrom/RPM-GPG-KEY → importar la firma digital de la llave pública. rpm --checksig package.rpm → verificar la integridad de un paquete rpm. rpm -qa gpg-pubkey → verificar la integridad de todos los paquetes rpm instalados. rpm -V package_name → chequear el tamaño del fichero, licencias, tipos, dueño, grupo, chequeo de res rpm -Va → chequear todos los paquetes rpm instalados en el sistema. Usar con cuidado. rpm -Vp package.rpm → verificar un paquete rpm no instalado todavía. rpm2cpio package.rpm | cpio --extract --make-directories *bin → extraer fichero ejecutable desde un rpm -ivh /usr/src/redhat/RPMS/`arch`/package.rpm → instalar un paquete construido desde una fuente r rpmbuild --rebuild package_name.src.rpm → construir un paquete rpm desde una fuente rpm. 3.21.13 Actualizador de paquetes yum (Fedora, Redhat y otros) yum yum yum yum yum yum yum yum yum yum install package_name → descargar e instalar un paquete rpm. localinstall package_name.rpm → este instalará un RPM y tratará de resolver todas las dependenci update package_name.rpm → actualizar todos los paquetes rpm instalados en el sistema. update package_name → modernizar / actualizar un paquete rpm. remove package_name → eliminar un paquete rpm. list → listar todos los paquetes instalados en el sistema. search package_name → Encontrar un paquete en repositorio rpm. clean packages → limpiar un caché rpm borrando los paquetes descargados. clean headers → eliminar todos los ficheros de encabezamiento que el sistema usa para resolver l clean all → eliminar desde los paquetes caché y ficheros de encabezado. 3.21.14 Paquetes deb (Debian, Ubuntu y otros) dpkg dpkg dpkg dpkg dpkg dpkg dpkg dpkg -i package.deb → instalar / actualizar un paquete deb. -r package_name → eliminar un paquete deb del sistema. -l → mostrar todos los paquetes deb instalados en el sistema. -l | grep httpd → mostrar todos los paquetes deb con el nombre “httpd” -s package_name → obtener información en un paquete específico instalado en el sistema. -L package_name → mostar lista de ficheros dados por un paquete instalado en el sistema. --contents package.deb → mostrar lista de ficheros dados por un paquete no instalado todavía. -S /bin/ping → verificar cuál paquete pertenece a un fichero dado. 3.21.15 Actualizador de paquetes apt (Debian, Ubuntu y otros) apt-get install package_name → instalar / actualizar un paquete deb. apt-cdrom install package_name → instalar / actualizar un paquete deb desde un cdrom. apt-get update → actualizar la lista de paquetes. apt-get upgrade → actualizar todos los paquetes instalados. apt-get remove package_name → eliminar un paquete deb del sistema. apt-get check → verificar la correcta resolución de las dependencias. apt-get clean → limpiar cache desde los paquetes descargados. apt-cache search searched-package → retorna lista de paquetes que corresponde a la serie «paquetes b 96 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.21.16 Ver el contenido de un fichero cat file1 → ver los contenidos de un fichero comenzando desde la primera hilera. tac file1 → ver los contenidos de un fichero comenzando desde la última línea. more file1 → ver el contenido a lo largo de un fichero. less file1 → parecido al commando ‘more’ pero permite salvar el movimiento en el fichero así como el head -2 file1 → ver las dos primeras líneas de un fichero. tail -2 file1 → ver las dos últimas líneas de un fichero. tail -f /var/log/messages → ver en tiempo real qué ha sido añadido al fichero. 3.21.17 Manipulación de texto cat file1 file2 ... | command <> file1_in.txt_or_file1_out.txt → sintaxis general para la manipulaci cat file1 | command( sed, grep, awk, grep, etc...) > result.txt → sintaxis general para manipular un cat file1 | command( sed, grep, awk, grep, etc...) » result.txt → sintaxis general para manipular un grep Aug /var/log/messages → buscar palabras “Aug” en el fichero ‘/var/log/messages’. grep ^Aug /var/log/messages → buscar palabras que comienzan con “Aug” en fichero ‘/var/log/messages’ grep [0-9] /var/log/messages → seleccionar todas las líneas del fichero ‘/var/log/messages’ que cont grep Aug -R /var/log/ → buscar la cadena “Aug” en el directorio ‘/var/log’ y debajo. sed 's/string1/string2/g' ejemplo.txt → reemplazar en ejemplo.txt todas las ocurrencias de “string1” sed '/^$/d' ejemplo.txt → eliminar todas las líneas en blanco desde el ejemplo.txt sed '/ *#/d; /^$/d' ejemplo.txt → eliminar comentarios y líneas en blanco de ejemplo.txt echo 'ejemplo' | tr '[:lower:]' '[:upper:]‘ → convertir “ejemplo” de minúsculas a mayúsculas. sed -e '1d' ejemplo.txt → elimina la primera línea del fichero ejemplo.txt sed -n '/string1/p‘ → visualizar solamente las líneas que contienen la palabra “string1”. 3.21.18 Establecer caracter y conversión de ficheros dos2unix filedos.txt fileunix.txt → convertir un formato de fichero texto desde MSDOS a UNIX. unix2dos fileunix.txt filedos.txt → convertir un formato de fichero de texto desde UNIX a MSDOS. recode ..HTML < page.txt > page.html → convertir un fichero de texto en html. recode -l | more → mostrar todas las conversiones de formato disponibles. 3.21.19 Análisis del sistema de ficheros badblocks -v /dev/hda1 → Chequear los bloques defectuosos en el disco hda1. fsck /dev/hda1 → reparar / chequear la integridad del fichero del sistema Linux en el disco hda1. fsck.ext2 /dev/hda1 → reparar / chequear la integridad del fichero del sistema ext 2 en el disco hda e2fsck /dev/hda1 → reparar / chequear la integridad del fichero del sistema ext 2 en el disco hda1. e2fsck -j /dev/hda1 → reparar / chequear la integridad del fichero del sistema ext 3 en el disco hda fsck.ext3 /dev/hda1 → reparar / chequear la integridad del fichero del sistema ext 3 en el disco hda fsck.vfat /dev/hda1 → reparar / chequear la integridad del fichero sistema fat en el disco hda1. fsck.msdos /dev/hda1 → reparar / chequear la integridad de un fichero del sistema dos en el disco hd dosfsck /dev/hda1 → reparar / chequear la integridad de un fichero del sistema dos en el disco hda1. 3.21.20 Formatear un sistema de ficheros mkfs /dev/hda1 → crear un fichero de sistema tipo Linux en la partición hda1. mke2fs /dev/hda1 → crear un fichero de sistema tipo Linux ext 2 en hda1. mke2fs -j /dev/hda1 → crear un fichero de sistema tipo Linux ext3 (periódico) en la partición hda1. mkfs -t vfat 32 -F /dev/hda1 → crear un fichero de sistema FAT32 en hda1. 3.21. Comandos Utiles 97 Apuntes Informatica Documentation, Publicación 1.0.0 fdformat -n /dev/fd0 → formatear un disco flooply. mkswap /dev/hda3 → crear un fichero de sistema swap. 3.21.21 Partición de sistema swap mkswap /dev/hda3 → crear fichero de sistema swap. swapon /dev/hda3 → activando una nueva partición swap. swapon /dev/hda2 /dev/hdb3 → activar dos particiones swap. 3.21.22 Salvas dump -0aj -f /tmp/home0.bak /home → hacer una salva completa del directorio ‘/home’. dump -1aj -f /tmp/home0.bak /home → hacer una salva incremental del directorio ‘/home’. restore -if /tmp/home0.bak → restaurando una salva interactivamente. rsync -rogpav --delete /home /tmp → sincronización entre directorios. rsync -rogpav -e ssh --delete /home ip_address:/tmp → rsync a través del túnelSSH. rsync -az -e ssh --delete ip_addr:/home/public /home/local → sincronizar un directorio local con un rsync -az -e ssh --delete /home/local ip_addr:/home/public → sincronizar un directorio remoto con un dd bs=1M if=/dev/hda | gzip | ssh user@ip_addr 'dd of=hda.gz‘ → hacer una salva de un disco duro en dd if=/dev/sda of=/tmp/file1 → salvar el contenido de un disco duro a un fichero. (En este caso el d tar -Puf backup.tar /home/user → hacer una salva incremental del directorio ‘/home/user’. tar -czv --exclude=/root/dir1/* -f /var/salvas/cfg_$(date +%F_%H%M).tgz /etc /root → salvar los dire ( cd /tmp/local/ && tar c . ) | ssh -C user@ip_addr 'cd /home/share/ && tar x -p‘ → copiar el conten ( tar c /home ) | ssh -C user@ip_addr 'cd /home/backup-home && tar x -p‘ → copiar un directorio loca tar cf - . | (cd /tmp/backup ; tar xf - ) → copia local conservando las licencias y enlaces desde un find /home/user1 -name '*.txt' | xargs cp -av --target-directory=/home/backup/ --parents → encontrar find /var/log -name '*.log' | tar cv --files-from=- | bzip2 > log.tar.bz2→ encontrar todos los fiche dd if=/dev/hda of=/dev/fd0 bs=512 count=1 → hacer una copia del MRB (Master Boot Record) a un disco dd if=/dev/fd0 of=/dev/hda bs=512 count=1 → restaurar la copia del MBR (Master Boot Record) salvada 3.21.23 CDROM cdrecord -v gracetime=2 dev=/dev/cdrom -eject blank=fast -force → limpiar o borrar un cd regrabable. mkisofs /dev/cdrom > cd.iso → crear una imagen iso de cdrom en disco. mkisofs /dev/cdrom | gzip > cd_iso.gz → crear una imagen comprimida iso de cdrom en disco. mkisofs -J -allow-leading-dots -R -V “Label CD” -iso-level 4 -o ./cd.iso data_cd → crear una imagen cdrecord -v dev=/dev/cdrom cd.iso → quemar una imagen iso. gzip -dc cd_iso.gz | cdrecord dev=/dev/cdrom - → quemar una imagen iso comprimida. mount -t udf,iso9660 -o loop cd.iso /mnt/iso → montar una imagen iso. cd-paranoia -B → llevar canciones de un cd a ficheros wav. cd-paranoia -- ”-3” → llevar las 3 primeras canciones de un cd a ficheros wav. cdrecord --scanbus → escanear bus para identificar el canal scsi. dd if=/dev/hdc | md5sum → hacer funcionar un md5sum en un dispositivo, como un CD. eject -v → expulsar un medio o disco extraíble, ofreciendo información adicional. 3.21.24 Trabajo con la red (LAN Y WIFI) ifconfig eth0 → mostrar la configuración de una tarjeta de red Ethernet. ifup eth0 → activar una interface ‘eth0. ifdown eth0 → deshabilitar una interface ‘eth0. ifconfig eth0 192.168.1.1 netmask 255.255.255.0 → configurar una dirección IP. 98 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 ifconfig eth0 promisc → configurar ‘eth0en modo común para obtener los paquetes (sniffing). dhclient eth0 → activar la interface ‘eth0 en modo dhcp. route -n → mostrar mesa de recorrido. route add -net 0/0 gw IP_Gateway → configurar entrada predeterminada. route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.1.1 → configurar ruta estática para buscar route del 0/0 gw IP_gateway → eliminar la ruta estática. echo “1” > /proc/sys/net/ipv4/ip_forward → activar el recorrido ip. hostname → mostrar el nombre del host del sistema. host www.example.com → buscar el nombre del host para resolver el nombre a una dirección ip(1). nslookup www.example.com → buscar el nombre del host para resolver el nombre a una direccióm ip y vi ip link show → mostar el estado de enlace de todas las interfaces. mii-tool eth0 → mostar el estado de enlace de ‘eth0. ethtool eth0 → mostrar las estadísticas de tarjeta de red ‘eth0. netstat -tup → mostrar todas las conexiones de red activas y sus PID. netstat -tupl → mostrar todos los servicios de escucha de red en el sistema y sus PID. netstat -punta → mostrar todas las conexiones activas por dirección IP y puerto. tcpdump tcp port 80 → mostrar todo el tráfico HTTP. iwlist scan → mostrar las redes inalámbricas. iwconfig eth1 → mostrar la configuración de una tarjeta de red inalámbrica. whois www.example.com → buscar en base de datos Whois. iftop -nNP -i eth0 → mostrar en tiempo real las conexiones abiertas en eth0 y su tasa de transferenc sockstat → mostrar información sobre las conexiones abiertas. arp-scan -l → descubrir en la red las direcciones IP y MAC. 3.21.25 Redes de Microsoft Windows (Samba) nbtscan ip_addr → resolución de nombre de red bios. nmblookup -A ip_addr → resolución de nombre de red bios. smbclient -L ip_addr/hostname → mostrar acciones remotas de un host en windows. 3.21.26 Cortafuegos (iptables) iptables -t filter -L → mostrar todas las cadenas de la tabla de filtro. iptables -t nat -L → mostrar todas las cadenas de la tabla nat. iptables -t filter -F → limpiar todas las reglas de la tabla de filtro. iptables -t nat -F → limpiar todas las reglas de la tabla nat. iptables -t filter -X → borrar cualquier cadena creada por el usuario. iptables -t filter -A INPUT -p tcp --dport telnet -j ACCEPT → permitir las conexiones telnet para en iptables -t filter -A OUTPUT -p tcp --dport http -j DROP → bloquear las conexiones HTTP para salir. iptables -t filter -A FORWARD -p tcp --dport pop3 -j ACCEPT → permitir las conexiones POP a una cade iptables -t filter -A INPUT -p tcp -m multiport --dports 80,443,8080 -m state --state NEW -m limit -iptables -t filter -A INPUT -p tcp -m multiport --dports 80,443,8080 -m state --state ESTABLISHED,REL iptables -t filter -A INPUT -j LOG --log-prefix “DROP INPUT” → registrando una cadena de entrada. iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE → configurar un PAT (Puerto de traducción de di iptables -t nat -A POSTROUTING -s 192.168.0.127 -o eth0 -j SNAT --to-source 169.158.158.169 → enruta iptables -t nat -A PREROUTING -d 192.168.0.1 -p tcp -m tcp --dport 22 -j DNAT --to-destination 10.0.0 iptables -t nat -S → Listar todas las reglas activas en la tabla nat. iptables-save -c > archivo → Salvar las reglas en un archivo (incluyendo los contadores de paquetes iptables-restore -c < archivo → Restaurar las reglas desde un archivo (incluyendo los contadores de 3.21. Comandos Utiles 99 Apuntes Informatica Documentation, Publicación 1.0.0 3.21.27 Monitoreando y depurando top → mostrar las tareas de linux usando la mayoría cpu. htop → mostrar y gestionar las tareas con una interfaz amistosa. ps -eafw → muestra las tareas Linux. ps -e -o pid,args --forest → muestra las tareas Linux en un modo jerárquico. ps aux | grep -i wget → listar todas las tareas activas que incluyen el comando wget (sintaxis BSD). pstree → mostrar un árbol sistema de procesos. kill -9 ID_Processo → forzar el cierre de un proceso y terminarlo. kill -1 ID_Processo → forzar un proceso para recargar la configuración. killall Nombre_Proceso → terminar un proceso por el nombre del comando y no por el ID. lsof -p $$ → mostrar una lista de ficheros abiertos por procesos. lsof /home/user1 → muestra una lista de ficheros abiertos en un camino dado del sistema. strace -c ls >/dev/null → mostrar las llamadas del sistema hechas y recibidas por un proceso. strace -f -e open ls >/dev/null → mostrar las llamadas a la biblioteca. watch -n1 'cat /proc/interrupts‘ → mostrar interrupciones en tiempo real. last reboot → mostrar historial de reinicio. lsmod → mostrar el kernel cargado. free -m → muestra el estado de la RAM en megabytes. smartctl -A /dev/hda → monitorear la fiabilidad de un disco duro a través de SMART. smartctl -i /dev/hda → chequear si SMART está activado en un disco duro. tail /var/log/dmesg → mostrar eventos inherentes al proceso de carga del kernel. tail /var/log/messages → mostrar los eventos del sistema. multitail --follow-all /var/log/dmesg /var/log/messages → mostrar dos registros de eventos en una mi 3.21.28 Otros comandos útiles apropos palabraclave → mostrar una lista de comandos que pertenecen a las palabras claves de un prog man ping → mostrar las páginas del manual on-line; por ejemplo, en un comando ping, usar la opción ‘ man -t ping | ps2pdf - ping.pdf → convertir las páginas del manual del comando ping en un archivo pd mkbootdisk --device /dev/fd0 `uname -r` → crear un floppy boteable. gpg -c file1 → codificar un fichero con guardia de seguridad GNU. gpg file1.gpg → decodificar un fichero con Guardia de seguridad GNU. wget -r www.example.com → descargar un sitio web completo. wget -c www.example.com/file.iso → descargar un fichero con la posibilidad de parar la descargar y r echo 'wget -c www.example.com/files.iso' | at 09:00 → Comenzar una descarga a cualquier hora. En est ldd /usr/bin/ssh → mostrar las bibliotecas compartidas requeridas por el programa ssh. alias hh='history‘ → colocar un alias para un commando -hh= Historial. chsh → cambiar el comando Shell. chsh --list-shells → es un comando adecuado para saber si tienes que hacer remoto en otra terminal. who -a → mostrar quien está registrado, e imprimir hora del último sistema de importación, procesos echo “128*1024*1024” | bc → calcular desde la consola el tamaño en bytes de 128MiB. sudo !! → ejecutar como superusuario el último comando tecleado. clear → limpiar la pantalla. uncomando > archivodesalida.txt 2>&1 → ejecuta un comando y redirige la salida a un archivo, combina uncomando | tee archivodesalida.txt → ejecuta un comando, muestra la salida en la pantalla y simultá 3.22 Contar lineas de un proyecto Fuentes https://github.com/AlDanial/cloc http://stackoverflow.com/questions/26881441/can-you-get-the-number-of-lines-of-code-from-a-githubrepository 100 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.22.1 cloc dnf install cloc Para contar un proyecto en Git se puede usar este script (ya que un proyecto alojado, se omite todo lo que uno no ha hecho). vim cloc-git #!/usr/bin/env bash git clone --depth 1 "$1" temp-linecount-repo && printf "('temp-linecount-repo' will be deleted automatically)\n\n\n" && cloc temp-linecount-repo && rm -rf temp-linecount-repo chmod +x cloc-git sudo mv cloc-git /usr/local/bin Ejemplo: cloc-git git@gitlab.com:snicoper/oferventa.git 3.23 Crear grupos y añadir usuarios a grupos Crear un grupo goupadd nombre_grupo Crear un usuario que pertenezca a un grupo, entre () es un ejemplo. adduser -c "Comentario (Git users)" -g nombre_grupo (git) nombre_usuario passwd nombre_usuario Otra manera de añadir a un usuario seria adduser nombre_usuario passwd nombre_usuario usermod -a -G nombre_grupo nombre_usuario 3.24 Diferencias entre adduser y useradd No es lo mismo “adduser” que “useradd”, ambos dan de alta usuarios pero el primero es para generar estructura y el otro no. adduser es para usuarios humanos. useradd es para usuarios de sistema. 3.23. Crear grupos y añadir usuarios a grupos 101 Apuntes Informatica Documentation, Publicación 1.0.0 3.25 Instalar Dropbox 3.25.1 GNOME Advertencia: Posiblemente des-actualizado su yum install -y wget Addition yum repo file from Dropbox wget http://dl.dropbox.com/u/30876345/repo/dropbox.repo mv dropbox.repo /etc/yum.repos.d Install Dropbox yum install -y nautilus-dropbox 3.25.2 KDE cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf - Autoarranque al iniciar en el sistema ln -s .dropbox-dist/dropboxd .kde/Autostart/dropboxd Iniciar por primera vez ~/.dropbox-dist/dropboxd & Nota: No recuerdo si había que ponerlo en inicio de sesión o no 3.26 Formatear discos con mkfs Prudencia: Cuidado con estos comando que pueden ser peligrosos, asegurarse de poner bien las particiones con las que se quiere operar. Desmontar la partición umount /dev/sdb? 3.26.1 FAT mkfs.vfat /dev/sdb1 # Lo deja en fat-16? mkfs.vfat -n pen4 -F 32 /dev/sdb1 # -n para label 102 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.26.2 Ext2, 3, 4 mkfs -t ext? /dev/sdb? 3.26.3 Swap mkswap /dev/sdb? btrfs mkfs.btrfs -f /dev/sdb? Poner label en una partición e2label /dev/sda5 nombre_label 3.27 Generar clave para SSH ssh-keygen -t rsa -b 4096 # Agregar clave SSH al agente ssh (evitar tener que poner el passphrase siempre) ssh-add Si ssh-add devuelve Could not open a connection to your authentication agent. eval `ssh-agent -s` ssh-add La carpeta ~/.ssh debe tener permisos 700 y los archivos de dentro de ~/.ssh han de ser de 600 chmod 700 ~/.ssh chmod 600 ~/.ssh/* 3.28 Iconos Numix mkdir ~/souces cd ~/sources git clone https://github.com/numixproject/numix-icon-theme.git git clone https://github.com/numixproject/numix-icon-theme-circle.git mkdir ~/.local/share/icons cd ~/.local/share/icons ln ln ln ln -s -s -s -s ~/sources/numix-icon-theme/Numix Numix ~/sources/numix-icon-theme/Numix-Light Numix-Light ~/sources/numix-icon-theme-circle/Numix-Circle Numix-Circle ~/sources/numix-icon-theme-circle/Numix-Circle-Light Numix-Circle-Light 3.27. Generar clave para SSH 103 Apuntes Informatica Documentation, Publicación 1.0.0 3.29 Instalacion Discord De momento no hay una versión final, pero si quieres estar hablando con tus colegas, quizá te pueda servir. Todo se hace como súper usuario (su) 3.29.1 Requisitos dnf install libXScrnSaver 3.29.2 Instalacion Descargar de GitHub el .tar.gz y descomprimir, por ultimo ir al path donde este el descomprimido y como súper usuario: mv DiscordCanary /opt/discord chmod +x /opt/discord/DiscordCanary ln -s /opt/discord/DiscordCanary /usr/local/bin/discord Por ultimo, crear un enlace al menú. vim /usr/share/applications/discord.desktop Añadimos: [Desktop Entry] Encoding=UTF-8 Name=Discord Comment=Chat Exec=discord %U Icon=/opt/discord/discord.png Terminal=false Type=Application StartupNotify=true 3.30 Instalación de Memcached 3.30.1 Fedora yum -y install memcached systemctl enable memcached.service systemctl start memcached.service Para editar la configuración vim /etc/sysconfig/memcached 3.30.2 Ubuntu 104 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 sudo apt-get install memcached libmemcached-tools Para editar la configuración sudo vim /etc/memcached.conf 3.31 Instalación MongoDb 3.31.1 Fedora dnf install mongodb mongodb-server systemctl enable mongod.service systemctl start mongod.service 3.31.2 Ubuntu sudo apt-get install mongodb mongodb-server 3.32 Instalación NodeJS 3.32.1 Instalación sudo dnf -y install nodejs npm Si después se actualiza npm con sudo npm install npm -g a la hora de actualizar el paquete nodejs dará problemas. Paquetes que instalo Los linters, se instalan a nivel local en los proyectos, no son necesarios. # Comunes sudo npm install -g bower sudo npm install -g gulp sudo npm install -g node-sass # Opcionales sudo npm install -g npm-check-updates sudo npm install -g babel-cli sudo npm install -g webpack # Linters sudo npm install sudo npm install sudo npm install sudo npm install -g -g -g -g eslint htmlhint stylelint stylelint-config-standard 3.31. Instalación MongoDb 105 Apuntes Informatica Documentation, Publicación 1.0.0 3.32.2 Algunos comandos utiles # Muestra los paquetes para actualizar (no actualizar npm) npm outdated -g --depth=0 # Listar todos los paquetes npm list -g --depth=0 3.33 Instalar Golang sudo dnf install golang Obtener la ultima version https://golang.org/dl/ .. code-block:: bash sudo tar -C /usr/local -xzf go1.7.1.linux-amd64.tar.gz Añadir al PATH vim ~/.bashrc # Golang export PATH=$PATH:/usr/local/go/bin export GOPATH=$HOME/.go 3.34 Instalar Libsass y SassC Fuentes http://crocodillon.com/blog/how-to-install-sassc-and-libsass-on-ubuntu — 3.34.1 Pre Requisitos Advertencia: TODO: Poner paquetes de compilación requeridos su cd /usr/local/lib git clone https://github.com/hcatlin/sassc.git git clone https://github.com/hcatlin/libsass.git Añadir SASS_LIBSASS_PATH al path para todos los usuarios. vim /etc/profile.d/sassc.sh export SASS_LIBSASS_PATH=/usr/local/lib/libsass source /etc/profile cd /usr/local/lib/sassc make chmod +x bin/sassc 106 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 cd /usr/local/bin/ ln -s ../lib/sassc/bin/sassc sassc 3.35 Instalar Mono Monodevelop Xsp DESACTUALIZADO! Fuentes http://www.mono-project.com/docs/getting-started/install/linux/ 3.35.1 Fedora Centos Añadir repo sudo rpm --import "https://pgp.mit.edu/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D # Fedora sudo dnf config-manager --add-repo http://download.mono-project.com/repo/centos/ # Centos sudo yum-config-manager --add-repo http://download.mono-project.com/repo/centos/ Instalar # yum para centos sudo dnf install mono-complete xsp monodevelop 3.35.2 Ubuntu Advertencia: No probado... Añadir repo sudo apt-key adv --keyserver pgp.mit.edu --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list. Instalar sudo apt install mono-complete xsp monodevelop 3.35.3 Ubuntu Fedora Como usuario: mozroots --import --sync Por ultimo dar permisos. 3.35. Instalar Mono Monodevelop Xsp 107 Apuntes Informatica Documentation, Publicación 1.0.0 sudo mkdir -p /etc/mono/registry/LocalMachine sudo chmod g+rwx /etc/mono/registry sudo chmod g+rwx /etc/mono/registry/LocalMachine 3.36 Mostrar Imagenes BIN, ISO, CUE, etc. 3.36.1 Fuente: http://bronch.wordpress.com/2006/05/24/como-montar-archivos-iso-bin-mdf-y-nrg-en-linux/ Nota: [ Créditos: este “howto” está basado en parte en las instrucciones que da Rodrigo Perez en este post aunque no he incluido algunos de sus métodos porque no los he probado personalmente. Además se ha utilizado información encontrada en los foros de Ubuntu-es.org así como en la Guia-Ubuntu -versión Breezy-. Para los archivos IMG se ha usado la información encontrada en este foro. Las instrucciones para convertir imágenes DAA las encontré en esta guía que además incluye otras instrucciones para manipular archivos DAA.) Linux tiene la posibilidad de montar las imágenes de cd/dvd sin tener que grabarlas. Asumiremos que usas una distribución que usa “apt” para instalar y actualizar paquetes, este es el caso de debian, ubuntu, suse,etc. Asumiremos también que sabes como crear directorios y que sabes qué es “montar” un sistema de ficheros. Vamos al grano. Con unos cuantos comandos de consola podremos montar distintos tipos de imágenes de CD/DVD fácilmente: 3.36.2 Lo más básico, montar una imagen ISO: sudo mount -t iso9660 -o loop archivo.iso /directorio/de/montaje 3.36.3 Montando imágenes BIN y CUE: Para poder montar estos archivos necesitas convertirlos antes a imagen ISO, esto lo puedes hacer con el programa bchunk. (Si no tienes instalado bchunk) sudo apt-get install bchunk Nota: si así no puedes instalarlo puede encontrar el programa aqui : bchunk y cuando se haya instalado procederemos a convertir la imagen bin con su archivo cue correspondiente a un solo archivo iso: bchunk archivo.bin archivo.cue nuevonombre.iso Ahora ya tendrás un nuevo archivo iso que podrás montar como se explica más arriba. 3.36.4 Montar imágenes NRG (imágenes de Nero Burning Rom): Las imagenes NRG pueden ser montadas directamente sin necesidad de convertirlas: 108 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 mount -t iso9660 -o loop,offset=307200 imagen.nrg /directorio/de/montaje Si tienes algún problema con ese método o deseas convertir la imagen NRG a ISO deberás usar el programa nrg2iso, para instalarlo haremos: sudo apt-get install nrg2iso si así no puedes instalarlo puede encontrar el programa aquí: Nrg2Iso y cuando ya esté instalado, para convertir la imagen nrg2iso archivo.nrg nuevoarchivo.iso y para montar la imagen ISO simplemente debes seguir las instrucciones detalladas más arriba 3.36.5 Montar imágenes MDF y MDS De nuevo utilizaremos un programa para convertir antes la imagen mdf a iso. El programa tiene el original nombre de mdf2iso. Para instalarlo: sudo apt-get install mdf2iso si así no puedes instalarlo puede encontrar el programa aquí: Mdf2Iso) y una vez instalado convertiremos el archivo MDF a ISO mdf2iso archivo.mdf nuevaimagen.iso 3.36.6 Montar imágenes IMG Usaremos el programa CCD2ISO. Este programa no lo he podido descargar desde los repositorios oficiales de Ubuntu pero de todos modos no estaría de más que intentases instalarlo por apt-get así: sudo apt-get install ccd2iso Si de este modo no puedes instalarlo puedes seguir las instrucciones de esta página para bajar el paquete deb de ccd2iso e instalarlo facilmente. Si por cualquier motivo no pudieses conseguir el programa por esos dos métodos siempre puedes descargarlo desde su página: ir a Ccd2Iso (ojo, tendrás que compilarlo) Para instalarlo de este último modo descargamos el archivo que sera algo así como “ccd2iso-0.2.tar.gz” (puede variar la versión) y primero lo descomprimimos así: tar -xzvf ccd2iso-0.2.tar.gz Ahora que tendremos una carpeta llamada “ccd2iso”, hacemos lo siguiente: cd ccd2iso ./configure make make install Con esto ya tendremos instalado el programa ccd2iso. Finalmente para convertir la imagen ccd a iso hacemos: ccd2iso imagen.img imagen.iso Y montaremos la imagen iso recien creada como se explica más arriba en esta misma guía. 3.36. Mostrar Imagenes BIN, ISO, CUE, etc. 109 Apuntes Informatica Documentation, Publicación 1.0.0 3.36.7 Montar imágenes DAA El formato DAA es un formato que utiliza el programa Poweriso. Durante algún tiempo este formato resultaba muy dificil de utilizar en Linux (no había versión de Poweriso para linux y la emulación con wine no funcionaba). Finalmente los creadores del programa sacaron una versión gratuita de su programa para Linux que además nos sirve para convertir otros formatos. Pero vamos al grano, para convertir una imagen DAA a ISO primero necesitaremos la versión linux de poweriso que podemos bajar desde esta página (parte de abajo) o bien de esta forma : wget http://poweriso.com/poweriso.tar.gz Descomprimimos tar -zxvf poweriso.tar.gz Y convertimos a ISO: ./poweriso convert imagen.daa -o nuevaimagen.iso (Instrucciones para montar la imagen iso, al principio de esta guía) 3.37 Montar partición SSH al iniciar sistema 3.37.1 Fuentes https://wiki.archlinux.org/index.php/Sshfs 3.37.2 Fedora yum install fuse-sshfs vim /etc/fstab snicoper@192.168.1.33:/home/snicoper /run/media/snicoper/srv1 mount /run/media/snicoper/srv1 fuse.sshfs noauto,x-systemd.automount, 3.38 Montar particiones al iniciar sistema Nota: Ver las particiones que se quiere montar con fdisk -l o df Nota: La única diferencia entre Fedora y Ubuntu es donde montan las carpetas. Fedora lo hace en /run/media/nombre_usuario/ y Ubuntu lo hace en /media/nombre_usuario 3.38.1 Fedora ntfs Desmontar partición (si esta montada) y crear carpeta data 110 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 su umount /run/media/snicoper/data mkdir -p /run/media/snicoper/data vim /etc/fstab Insertar al final ### data /dev/sda6 /run/media/snicoper/data ntfs defaults,rw,users,auto,iocharset=utf8,umask=0 Montar particiones mount -a 3.38.2 Ubuntu ntfs sudo umount /media/snicoper/data mkdir -p /media/snicoper/data vim /etc/fstab /dev/sda5 /media/snicoper/data ntfs defaults,rw,users,auto,iocharset=utf8,umask=0 mount -a 3.38.3 Fedora ext4 mkdir -p /run/media/snicoper/data vim /etc/fstab /dev/sda5 /run/media/snicoper/data ext4 defaults 1 2 Si es la primera vez que se crea la partición, crear una carpeta mkdir /run/media/snicoper/data/snicoper chown snicoper:snicoper /run/media/snicoper/data/snicoper # Para poder mover archivos a la papelera. mkdir /run/media/snicoper/data/.Trash-1000 chown snicoper: /run/media/snicoper/data/.Trash-1000 3.38.4 Fedora btrfs /dev/sdaX /run/media/snicoper/data btrfs defaults,user,auto 0 2 3.39 Redimensionar una imagen Cambiar el tamaño de una imagen en % 3.39. Redimensionar una imagen 111 Apuntes Informatica Documentation, Publicación 1.0.0 convert imagen.png -resize 50% carpeta/imagen.png Cambiar el tañano de una imagen en pixeles convert imagen.png -resize 60x60 carpeta/imagen.png 3.40 Saber donde esta un “ejecutable” which php 3.41 Saber temperatura del PC Fuentes http://blog.desdelinux.net/sensors-conoce-todas-las-temperaturas-de-tu-ordenador/ sudo apt-get install lm-sensors La terminal te puede mostrar la temperatura en tiempo real con tan solo poner: watch -n 01 sensors 3.42 Source Code Pro Fuentes http://sourceforge.net/projects/sourcecodepro.adobe/files/ https://github.com/adobe-fonts/source-code-pro Descargar de sourceforge SourceCodePro_FontsOnly-(version).zip. cd SourceCodePro_FontsOnly-(version)/ mkdir source-code-pro # mv OTF/* source-code-pro mv TTF/* source-code-pro sudo mv source-code-pro /usr/share/fonts/ sudo fc-cache 3.43 Tip, crear varios documentos con touch Crear varios documentos con touch en un directorio diferente al actual. touch other/folder/{file1.txt,file2.txt} 112 Capítulo 3. Linux Apuntes Informatica Documentation, Publicación 1.0.0 3.44 Tunel SSH ssh snicoper@lxmaq1.workspace.local -L 3307:localhost:3306 -N 3307: Es el puerto que asigno a la maquina cliente 3306: El puerto del host Ahora desde el cliente mysql -h 127.0.0.1 -u root -p -P 3307 3.45 Ver permisos en octal de los archivos stat -c %a filename 3.46 Virtualbox, problema con Alt Gr Si en la maquina virtual al pultar AltGr + 2 (@), no sale la (@), usar esta combinación: Pulsar AltGr (Mantener pulsada), pulsar Ctrl (solo pulsar y soltar) + tecla a escribir(@). 3.44. Tunel SSH 113 Apuntes Informatica Documentation, Publicación 1.0.0 114 Capítulo 3. Linux CAPÍTULO 4 Programacion Categorias: 4.1 Apuntes sin clasificar Categorias: 4.1.1 Calcular porcentaje Fuentes http://primaria.aulafacil.com/matematicas-sexto-primaria/Curso/Lecc-16.htm Incrementar un % Incrementar un % a una cantidad. Cantidad inicial -> 200 % a incrementar -> 1.10 200 * 1.10 = 220 Por el ejemplo, si el porcentaje que se quiere averiguar es 8 %, 8 es un integer y para poderlo pasar a %, se debe hacer la conversión. Decrementar un % Cantidad actual 24 % a incrementar 18 18 / 100 = 0.18 1 - 0.18 = 0.82 0.82 * 24 = 19.68 115 Apuntes Informatica Documentation, Publicación 1.0.0 Obtener que % se ha aplicado a una cantidad. Para averiguarlo, debemos saber 2 datos: Cantidad total -> 160 Cantidad incrementada del % -> 30 100 * (cantidad_porcentaje / total) 100 * (30 / 160) = 18,75 % 4.1.2 Permisos de archivos básico Nota: Aunque lo apunte de un libro de php, en realidad es parte del sistema de Linux. Dependiendo de los permisos, lo que repercute en archivos y directorios. Permisos read write Lo que permite en un directorio Ver su contenido (ls) Crear o eliminar archivos en el directorio. Lo que permite en un archivo Ver, Copiar, Imprimir, etc Modificar, renombrar o eliminarlo. Valores numéricos para permisos de archivos para clases de usuarios Orden Lectura Escritura Ejecución Propietario 400 200 100 Grupo 040 020 010 Otros 004 002 001 Es decir un archivo con permisos 700 seria que al propietario puede leer, escribir y ejecutar, pero el resto no podrían hacer ninguna de las cosas (-rwx——). Se suman los valores en cada columna y se obtiene los permisos, 777 es el máximo Para mas información leer el libro PHP y MySQL Practico para diseñadores y programadores web pagina 469 En Beginning PHP 5.3 da mas datos sobre los permisos y pone todos los números (pag 352) 1 No se puede leer, escribir o ejecutar el archivo 2 Sólo puede ejecutar el archivo 3 Sólo se pueden escribir en el fichero 4 Se puede escribir y ejecutar el archivo 5 Pueden leer y ejecutar el archivo 6 Puede leer y escribir en el fichero 7 Puede leer, escribir y ejecutar el archivo Para dar permisos con chmod() se ha de hacer de la siguiente manera: bool chmod(‘nombre_archivo.dat’, 0644); 4.1.3 Plantilla Atorm 116 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 <?xml version='1.0' encoding='utf-8'?> <feed xmlns='http://www.w3.org/2005/Atom' xml:lang='en'> <title>dive into mark</title> <subtitle>currently between addictions</subtitle> <id>tag:diveintomark.org,2001-07-29:/</id> <updated>2009-03-27T21:56:07Z</updated> <link rel='alternate' type='text/html' href='http://diveintomark.org/'/> <entry> <author> <name>Mark</name> <uri>http://diveintomark.org/</uri> </author> <title>Dive into history, 2009 edition</title> <link rel='alternate' type='text/html' href='http://diveintomark.org/archives/2009/03/27/dive-into-history-2009-edition'/> <id>tag:diveintomark.org,2009-03-27:/archives/20090327172042</id> <updated>2009-03-27T21:56:07Z</updated> <published>2009-03-27T17:20:42Z</published> <category scheme='http://diveintomark.org' term='diveintopython'/> <category scheme='http://diveintomark.org' term='docbook'/> <category scheme='http://diveintomark.org' term='html'/> <summary type='html'>Putting an entire chapter on one page sounds bloated, but consider this &amp;mdash; my longest chapter so far would be 75 printed pages, and it loads in under 5 seconds&amp;hellip; On dialup.</summary> </entry> <entry> <author> <name>Mark</name> <uri>http://diveintomark.org/</uri> </author> <title>Accessibility is a harsh mistress</title> <link rel='alternate' type='text/html' href='http://diveintomark.org/archives/2009/03/21/accessibility-is-a-harsh-mistress'/> <id>tag:diveintomark.org,2009-03-21:/archives/20090321200928</id> <updated>2009-03-22T01:05:37Z</updated> <published>2009-03-21T20:09:28Z</published> <category scheme='http://diveintomark.org' term='accessibility'/> <summary type='html'>The accessibility orthodoxy does not permit people to question the value of features that are rarely useful and rarely used.</summary> </entry> <entry> <author> <name>Mark</name> </author> <title>A gentle introduction to video encoding, part 1: container formats</title> <link rel='alternate' type='text/html' href='http://diveintomark.org/archives/2008/12/18/give-part-1-container-formats'/> <id>tag:diveintomark.org,2008-12-18:/archives/20081218155422</id> <updated>2009-01-11T19:39:22Z</updated> <published>2008-12-18T15:54:22Z</published> <category scheme='http://diveintomark.org' term='asf'/> <category scheme='http://diveintomark.org' term='avi'/> <category scheme='http://diveintomark.org' term='encoding'/> <category scheme='http://diveintomark.org' term='flv'/> <category scheme='http://diveintomark.org' term='GIVE'/> <category scheme='http://diveintomark.org' term='mp4'/> <category scheme='http://diveintomark.org' term='ogg'/> 4.1. Apuntes sin clasificar 117 Apuntes Informatica Documentation, Publicación 1.0.0 <category scheme='http://diveintomark.org' term='video'/> <summary type='html'>These notes will eventually become part of a tech talk on video encoding.</summary> </entry> </feed> 4.1.4 Plantilla RSS2 <?xml version="1.0" ?> <rss version="2.0"> <channel> <title>Ajax and XUL</title> <link>http://www.xul.fr/en/</link> <description>XML graphical interface etc...</description> <image> <url>http://www.xul.fr/xul-icon.gif</url> <link>http://www.xul.fr/en/index.php</link> </image> <item> <title>News of today</title> <link>http://www.xul.fr/en-xml-rss.html</link> <description>All you need to know about RSS</description> </item> <item> <title>News of tomorrows</title> <link>http://www.xul.fr/en-xml-rdf.html</link> <description>And now, all about RDF</description> </item> </channel> </rss> 4.1.5 Saber si un año es bisiesto if ((($year % 4 == 0) && ($year % 100 != 0)) || ($year % 400 == 0)) { $bisiesto = true; } 4.2 C# C# Lenguaje 4.2.1 Array Básico Arrays una dimensión Declarar e inicializar un array: 118 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 // Crear un array con 10 elementos sin rellenarlos string[] myArray = new string[10]; // Para asignar valores usar indices en los [] myArray[0] = "elemento"; // Crear array e insertarle valores int[] myArray = {1, 2, 3, 4, 5}; // Es equivalente a: int[] myArray = new int[5] {1, 2, 3, 4, 5}; // o int[] myArray = new int[5]; myArray[0] = 1; myArray[1] = 2; myArray[2] = 3; myArray[3] = 4; myArray[4] = 5; Multidimensional Arrays Son arrays de dos dimensiones, se puede pensar en ellas (siendo de 2 dimensiones) como filas y columnas en una tabla. Para declarar una se usa la siguiente sintaxis: int[,] matrix = new int[4, 2]; Esto crea una “tabla mas o menos así” x x x x x x x x Una manera rápida seria: int[,] matrix = { {1, 1}, {2, 2}, {3, 5}, {4, 5} }; Donde: 1 2 3 4 1 2 5 5 matrix[0, 2]; // 3 matrix[1, 2]; // 5 Arrays de Arrays También llamadas arrays escalonada, ya que cada fila puede tener un numero x de elementos. Un ejemplo rapido: 4.2. C# 119 Apuntes Informatica Documentation, Publicación 1.0.0 int[][] matrix = new int[3][]; matrix[0] = new int[5]; matrix[1] = new int[4]; matrix[2] = new int[2]; matrix[0][3] = 4; matrix[1][1] = 8; matrix[2][0] = 5; 0 0 0 4 0 0 8 0 0 5 0 Los elementos que no se hayan inicializado, su valor sera null, independientemente del tipo al que pertenezca el elemento. string[] nombres = new string[10]; int[] numeros = new int[10]; nombres[1]; // null numeros[1]; // null 4.2.2 Boxing y Unbonxing Fuentes http://msdn.microsoft.com/es-es/library/yz2be5wk.aspx Boxing se refiere a la conversión de un tipo valor a un tipo object ajustable. Unboxing es lo contrario, un tipo objeto a un tipo valor (siempre que sea posible), además se debe hacer de manera explícita. Boxing int i = 1; object o = i; Unbonxing int e = (int)o; La utilidad viene mas cuando se usan por ejemplo, listas using System.Collections; [......] ArrayList array = new ArrayList(); array.Add(12); array.Add(3); array.Add(123); Si ahora queremos obtener los valores y asignarlos a variables, como ArrayList no sabe los tipos de sus valores, debemos hacer Unboxing de manera explicita: 120 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 int num = (int)array[1]; Nota: Aun asi, si necesitamos listas de un tipo concreto, usar System.Collections.Generic 4.2.3 DirectorySeparator Path.DirectorySeparatorChar (Campo) 4.2.4 Character Commands Fuentes http://msdn.microsoft.com/en-us/library/system.char.aspx Muy útiles para comprobar un carácter dado. char.IsDigit(ch) char.IsLetter(ch) char.IsLetterOrDigit(ch) char.IsLower(ch) char.IsUpper(ch) char.IsPunctuation(ch) char.IsWhiteSpace(ch) returns true if the character is a digit (0 to 9) returns true if the character is a letter (a to z or A to Z) returns true if the character is a letter or a digit returns true if the character is a lower case letter returns true if the character is an upper case letter returns true if the character is a punctuation character returns true if the character is a space, tab or newline 4.2.5 Checked Unchecked Sirve para comprobar el desbordamiento, con checked lo comprueba, unchecked no lo hace. Por ejemplo byte a = 55; byte b = 210; byte result = (byte)(a + b); El comportamiento por defecto, depende de la configuración de compilación, pero creo que es unchecked. unchecked { byte a = 55; byte b = 210; byte result = (byte)(a + b); } El ejemplo anterior, dará como resultado 9, ya que un byte solo puede contener un entero entre 0 y 255. La suma es de 210 + 55 = 265 (supera en 10 al máximo), por lo que que cuando llega a 255 el siguiente numero es 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 que son los 10 extras. Con checked 4.2. C# 121 Apuntes Informatica Documentation, Publicación 1.0.0 checked { byte a = 55; byte b = 210; byte result = (byte)(a + b); } Lanzara una System.OverflowException Conclusión, si es importante que no sobrepase el máximo de un tipo, usar checked 4.2.6 Conversiones Implicitas Numericas 4.2.7 Creacion de un metodo con un param lambda Fuentes OrtizOL - Experiencias Construcción Software (xCSw) Me dejo un ejemplo para recordar. 122 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 using System; using System.Collections.Generic; namespace ConsolePracticas { class Program { static void Main(string[] args) { List<Person> persons = new List<Person> { new Person { Id = 1, Nombre = "snicoper" }, new Person { Id = 2, Nombre = "perico" }, new Person { Id = 3, Nombre = "palote" }, }; IEnumerable<Person> query = persons.MyWhere(p => p.Id > 1); foreach (Person ele in query) { Console.Write("{0}, ", ele.Nombre); // perico, palote, } Console.ReadLine(); } } public static class MyExtensions { public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> lista, Func<T, bool> predicate) { foreach (T element in lista) { if (predicate(element)) { yield return element; } } } } public class Person { public int Id { get; set; } public string Nombre { get; set; } } } 4.2. C# 123 Apuntes Informatica Documentation, Publicación 1.0.0 4.2.8 Descripcion Accesibilidad Accessibility public protected internal assemblies protected private Description No restrictions on access. Can be accessed in the declaring class or derived classes. Can be accessed by all types in the same assembly of the declaring class and other specifically named using the InternalsVisibleTo attribute. internal Any access granted by protected or internal. Only accessed by the declaring class. 4.2.9 Diferencia entre Class y Struct Fuentes http://geekswithblogs.net/BlackRabbitCoder/archive/2010/07/29/c-fundamentals-the-differences-betweenstruct-and-class.aspx La primera gran diferencia es que las clases son tipo referencia mientras que las structs son tipo valor. Algunas diferencias Nota: En geekswithblogs.net hay un articulo mucho mas completo. 124 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Feature Is a reference type? Is a value type? Can have nested Types (enum, class, struct)? Can have constants? Can have fields? Can have properties? Can have indexers Can have methods Can have Events Can have static members (constructors, fields, methods, properties, etc.)? Can inherit? Can implement interfaces? Can overload constructor? Can define default constructor? Can overload operators? Can be generic? Can be partial? Can be sealed? Can be referenced in instance members using this keyword? Needs new operator to create instance? StructClassNotes No Yes Yes No Yes Yes Yes Yes Yes Yes Campos de instancia estructura no se pueden inicializar, se inicializará automáticamente al valor por defecto. Yes Yes Yes Yes Yes Yes Yes Yes Las estructuras, al igual que las clases, pueden tener eventos, pero se debe tener cuidado de que no se suscribe a una copia de una estructura en lugar de la estructura que pretende. Yes Yes No Yes Las clases pueden heredar de otras clases (o de objeto por defecto). Las estructuras siempre heredan de System.ValueType y se sellan de manera implícita Yes Yes No Yes Sobrecarga de estructura del constructor no oculta constructor predeterminado No Yes El constructor predeterminado inicializa struct todos los campos de instancia a los valores por defecto y no se puede cambiar. Yes Yes Yes Yes Yes Yes Al- Yes Las estructuras siempre están sellados y no se pueden tener structs ways derivadas. Yes Yes No Yes Clases de C # deben instanciar usando new. Sin embargo, las estructuras no requieren esto. Mientras que New se puede utilizar en una estructura que llamar a un constructor, puede optar por no utilizar new e init los campos a ti mismo, pero hay que init todos los campos y los campos debe ser público! 4.2.10 Campos y Propiedades Un campo es el equivalente de una propiedad en PHP. private string nombre; Una propiedad es un setters/getter con posible lógica sobre un campo. public string Nombre { set { if (value.Length < 5) { // hacer algo } else { 4.2. C# 125 Apuntes Informatica Documentation, Publicación 1.0.0 nombre = value; } } get { return nombre; } } A groso modo, se puede decir que un campo(field) son como las propiedades en PHP y las propiedades son los métodos accesores en PHP. Internamente cuando lo convierte a ¿CIL?, crea métodos accesores como en PHP, es un atajo para el desarrollador. 4.2.11 IEnumerator Pequeño ejemplo que implementa IEnumerator con genéricos. class IntList<T> : IEnumerable<T> { private int count = 0; private T[] values; public int Count { get { return count; } } public IntList(int capacity) { values = new T[capacity]; } public void Add(T value) { values[count] = value; count++; } public T this[int index] { get { return values[index]; } set { values[index] = value; } } public IEnumerator<T> GetEnumerator() { for (int i = 0; i < count; i++) { yield return values[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } 126 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 4.2.12 Métodos de Extensión C# Fuentes http://msdn.microsoft.com/es-es/library/bb383977.aspx Cita de MSDN Ejemplo simple Los métodos de extensión deben estar en una clase static y el método también ha de ser static. public static clss StringExtension { public static string UcFirst(this string str) { if (str.Length == 0) { return string.Empty; } return string.Format("{0}{1}", str[0].ToUpper(), str.SubString(1)); } } El primer parámetro UcFirst(this string str) con this le decimos a que hace referencia, en este caso es un tipo string, pero podría ser cualquier tipo. Después del primer parámetro, se pueden poner tantos como se quiera, lo que al llamar al método, el “primer” argumento se omite. string nombre = "salvador"; Console.WriteLine(nombre.UcFirst()); // Salvador Al ser una extensión de string al nombre.MyExtension() es como si el método fuera parte del string. 4.2.13 new and override basico Fuentes http://msdn.microsoft.com/es-es/library/ms173153.aspx Cuando usar new y cuando usar virtual/override. Supongamos que tenemos 2 clases class A { public void MethodA() { Console.WriteLine("Metodo en clase A"); } 4.2. C# 127 Apuntes Informatica Documentation, Publicación 1.0.0 // Es lo mismo que: // public virtual void MethodA() // { // Console.WriteLine("Metodo en clase A"); // } } class B : A { public new void MethodA() { Console.WriteLine("Metodo en clase B"); } } class Test { public static void Main() { A a = new A(); B b = new B(); A ab = new B(); a.MethodA(); // Metodo en clase A b.MethodA(); // Metodo en clase B ab.MethodA(); // Metodo en clase A } } Ahora, si declaramos el método MethodA de la clase A como virtual y el MethodA de la clase B como override, el resultado es el siguiente: class A { public virtual void MethodA() { Console.WriteLine("Metodo en clase A"); } } class B : A { public override void MethodA() { Console.WriteLine("Metodo en clase B"); } } class Test { public static void Main() { A a = new A(); B b = new B(); A ab = new B(); a.MethodA(); // Metodo en clase A b.MethodA(); // Metodo en clase B 128 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 ab.MethodA(); // Metodo en clase B } } Con new, si una clase es downgradeada, mostrara el resultado del método base, en cambio con override, lo sobrescribe siempre y muestra el valor de la clase derivada. 4.2.14 Operadores sobrecargables Fuentes http://msdn.microsoft.com/es-es/library/8edha89s%28v=vs.80%29.aspx http://ortizol.blogspot.com.es/2014/04/receta-no-1-21-en-c-sobrecargar-un.html Ejemplo public struct Complex { public int real; public int imaginary; // Constructor. public Complex(int real, int imaginary) { this.real = real; this.imaginary = imaginary; } // Specify which operator to overload (+), // the types that can be added (two Complex objects), // and the return type (Complex). public static Complex operator +(Complex c1, Complex c2) { return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary); } // Override the ToString() method to display a complex number // in the traditional format: public override string ToString() { return (System.String.Format("{0} + {1}i", real, imaginary)); } } class TestComplex { static void Main() { Complex num1 = new Complex(2, 3); Complex num2 = new Complex(3, 4); // Add two Complex objects by using the overloaded + operator. Complex sum = num1 + num2; 4.2. C# 129 Apuntes Informatica Documentation, Publicación 1.0.0 // Print the numbers and the sum by using the overridden // ToString method. System.Console.WriteLine("First complex number: {0}", num1); System.Console.WriteLine("Second complex number: {0}", num2); System.Console.WriteLine("The sum of the two numbers: {0}", sum); // Keep the console window open in debug mode. System.Console.WriteLine("Press any key to exit."); System.Console.ReadKey(); } } /* Output: First complex number: 2 + 3i Second complex number: 3 + 4i The sum of the two numbers: 5 + 7i / * 4.2.15 ref and out Sirven para usar variables como referencias en los métodos. Tanto ref, como out, no se pueden usar en parámetros opcionales. Reglas de ref El parámetro pasado al método, ha de estar declarado e inicializado El método se le ha de añadir ‘ref’ (ref int i) Al llamar el método, en el parámetro se ha de volver a usar ‘ref’ LlamarMethod(ref i) Reglas de out El argumento dentro del método (referencia a), se le ha de dar un valor antes de que termine el método. Tanto el parámetro como el argumento, es necesario indicarlo con ‘out tipo nombre’ 4.2.16 Sufijos para tipos numéricos Fuentes http://www.esasp.net/2010/04/sufijos-para-tipos-de-datos-numericos.html long float double decimal uint ulong L F D (opcional?) M UI (opcional?) UL (opcional?) short, int, ushort No tienen sufijo. 130 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 4.2.17 Tipos C# to PostgreSQL Fuentes http://stackoverflow.com/questions/845458/postgresql-and-c-sharp-datatypes http://npgsql.projects.pgfoundry.org/docs/manual/UserManual.html Postgresql int8 bool bytea date float8 int4 money numeric float4 int2 text time timetz timestamp timestamptz interval varchar inet bit uuid array NpgsqlDbType Bigint Boolean Bytea Date Double Integer Money Numeric Real Smallint Text Time Time Timestamp TimestampTZ Interval Varchar Inet Bit Uuid Array System.DbType Enum Int64 Boolean Binary Date Double Int32 Decimal Decimal Single Int16 String Time Time DateTime DateTime Object String Object Boolean Guid Object .Net System Type Int64 Boolean Byte[] DateTime Double Int32 Decimal Decimal Single Int16 String DateTime DateTime DateTime DateTime TimeSpan String IPAddress Boolean Guid Array 4.2.18 Upcast y Downcast Fuentes http://www.programacion.com/foros/java-basico/que_es_downcasting_170402 Queremos guardar una serie de objetos Silla en un ArrayList. El ArrayList sólo admite objetos de tipo Object, pero como Silla hereda de Object (como todos los objetos) puedes meter sillas directamente en el ArrayList: ArrayList miLista = new ArrayList(); miLista.add(new Silla()); Cuando metes un objeto Silla en un ArrayList, Jaa hace un cast implícito al tipo Object. Esto se conoce como “upcasting”, es decir, moldear un objeto al tipo de una de sus superclases. Ahora bien, si necesitamos recuperar uno de esos objetos Silla, debemos hacer lo siguiente: Silla s = (Silla)miLista.get(0); El cast es necesario porque el método get() devuelve objetos de tipo Object. Pues bien, a esta operación se le llama “downcasting”, porque estás moldeando un objeto a una de sus subclases. 4.2. C# 131 Apuntes Informatica Documentation, Publicación 1.0.0 Ahora cuidado: no puedes moldear un objeto Silla a Object y luego moldear ese Object a Mesa, por ejemplo, porque no funcionará. Sólo puedes hacer upcasting y downcasting dentro de la jerarquía de herencia del objeto, o dicho de otra forma, sólo puedes moldear el objeto a una de las clases comprendidas entre la clase Object y el tipo original del objeto (ambos inclusive), pasando por todas sus superclases. 4.2.19 C# Virtual Fuentes http://msdn.microsoft.com/es-es/library/9fkccyh4.aspx La palabra clave virtual se utiliza para modificar un método, propiedad, indizador o declaración de evento y permite invalidar cualquiera de estos elementos en una clase derivada. No puede utilizar el modificador virtual con los modificadores static, abstract, private u override. Para poder sobre-escribir un método (por ejemplo) en una subclase, es necesario que la clase padre tenga declarado un virtual. Por ejemplo class A { public void Mostrar() {} } class B : A { public override void Mostrar() {} } La class B daría error, por que el método Mostrar() en la clase A, no se deja sobre-escribir, para poder hacerlo, vasta con declarar el método de la clase A como virtual. class A { public virtual void Mostrar() {} } class B : A { public override void Mostrar() {} } Cuando simplemente se quiere “sobre-escribir un método padre”: class A { public virtual void Mostrar() {} } class B : A { public new void Mostrar() {} } Ver new and override basico , para ver las diferencias entre new y override. Scripts 132 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 4.2.20 C# Scripts Calcular Tiempo de Ejecución de un Programa using System.Diagnogtics; Stopwatch sw = new Stopwatch(); sw.Start(); // También se puede inicializar con un método static Stopwatch sw = Stopwatch.StartNew(); int contador = 0; for (int i = 0; i < 27; i++) { for (int j = 0; j < 27; j++) { for (int k = 0; k < 22; k++) { for (int g = 0; g < 100000; g++) { contador++; } } } } Console.WriteLine(contador); sw.Stop(); Console.WriteLine(sw.Elapsed.TotalSeconds); Envío Email usando SMTP C# using System.Net.Mail; /// <summary> /// Enviar un email /// </summary> /// <returns>true en caso de éxito, false en caso contrario.</returns> public bool Send() { try { MailMessage mail = new MailMessage(); mail.IsBodyHtml = true; mail.From = new MailAddress("snicoper@gmail.com", "snicoper"); mail.To.Add(new MailAddress("snicoper@outlook.com", "Salvador Nicolas")); mail.Subject = "Mensaje de prueba desde C# .NET"; mail.Body = "<h1>Mensaje de prueba!!<h1>"; using (SmtpClient smtp = new SmtpClient()) { smtp.Host = "smtp.gmail.com"; smtp.Port = 587; smtp.EnableSsl = true; 4.2. C# 133 Apuntes Informatica Documentation, Publicación 1.0.0 System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential(); NetworkCred.UserName = "snicoper@gmail.com"; NetworkCred.Password = "123456"; smtp.UseDefaultCredentials = true; smtp.Credentials = NetworkCred; smtp.Send(mail); } } catch (Exception) { return false; } return true; } Nota: También puede interesar. https://github.com/jstedfast/MailKit https://github.com/jstedfast/MimeKit Lanzar Finalizador de Clase C# Fuentes http://stackoverflow.com/a/1987288 http://msdn.microsoft.com/es-es/library/system.idisposable.dispose%28v=vs.110%29.aspx http://canyouhearthebits.wordpress.com/2008/08/08/como-implementar-correctamente-idisposable/ Un finalizador de clase, es una método que se ejecuta cuando el objeto es destruido, pero no por el usuario, si no por el GC. En C# no existe el “destructor de clase”. Advertencia: Ver IDisposable(abajo) para hacer este tipo de cosas Mi problema fue con un código como el siguiente class Point { public Point() { Console.WriteLine(1); } ~Point() { Console.WriteLine(2); } } 134 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 class Program { static void Main(string[] args) { Point p = new Point(); p = null; Console.WriteLine(3); } } Resultado 1 3 2 En teoría, o según lo hace PHP, cuando se destruye un objeto (obj = null), o cuando finaliza por que ya no se referencia mas, el método __destruct() es llamado. En C#, que se llama finalilzador, no hace lo mismo, al menos no cuando se destruye de manera explicita asignándole ‘null’. Encontré en los comentarios un código, y al menos me hizo lo que esperaba que hiciera, que lanzara el finalizador en cuanto lo destruyera. Point p = new Point(); p = null; GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine(3); Ahora el resultado es 1 2 3 Interfaz IDisposable (Recomendado) Otra manera, seria que la clase implemente la interfaz IDisposable con un único miembro Dispose, dentro del método se podrían añadir la limpieza necesaria de la clase. Lectura Escritura archivos Básico Fuentes http://msdn.microsoft.com/es-es/library/system.io.filestream%28v=vs.110%29.aspx using System.IO Comprobar si un archivo existe 4.2. C# 135 Apuntes Informatica Documentation, Publicación 1.0.0 if (!File.Exists(filePath)) { throw new FileNotFoundException(); } Escribir en un archivo Si existe, y lo que queremos hacer es escribir en el: using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write)) { } Con FileMode, decimos el modo de abrir el archivo, ejeplo, Append, OpenOrCreate, etc. http://msdn.microsoft.com/es-es/library/system.io.filemode%28v=vs.110%29.aspx Con FileAccess, decimos el acceso al archivo, ejemplo, Read, ReadWrite o Write. Pienso que es la mejor manera de abrir un recurso, por que podemos decirle el modo y acceso al recurso. Ahora con StreamWriter, añadimos los datos. Cuando se usan varios recursos, es posible poner uno seguido del otro, como en el siguiente ejemplo. El compilador generará los bloques try-finally anidados apropiados. using (FileStream fs = new FileStream(archivo, FileMode.OpenOrCreate, FileAccess.Write)) using (StreamWriter sw = new StreamWriter(fs)) { sw.Write("Nuevo texto"); sw.WriteLine("Nueva linea"); } Leer de un archivo También es posible abrirlo con FileStream, pero como solo se trata de leerlo, tambien lo puedo hacer con StreamReader. Primero, seria comprobar si el archivo existe y en caso de existir, abrirlo using (StreamReader sr = new StreamReader(filePath)) { //Leer el archivo } Crear Excepciones personalizadas public class CountIsZeroException : Exception { public CountIsZeroException() { } public CountIsZeroException(string message) : base(message) { } 136 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 public CountIsZeroException(string message, Exception innerException) : base(message, innerException) { } } Redimensionar imagen C# using System.Drawing; using System.Drawing.Drawing2D; using System.IO; namespace HaveYouSeenMe.Models.Business { public class PetManagement { /// <summary> /// Redimensiona una imagen a un ancho/alto dado. /// </summary> /// <param name="filename">Nombre del archivo, incluida extension</param> /// <param name="filepath">Carpeta contenedora para guardar</param> /// <param name="thumbWi">Ancho de la imagen a redimensionar</param> /// <param name="thumbHi">Alto de la imagen a redimensionar</param> /// <param name="maintainAspect">Mantener proporciones ancho/alto?</param> public static void CreateThumbnail(string filename, string filepath, int thumbWi, int thumbHi, bool maintainAspect) { // Do nothing if the original is smaller than the designated // thumbnail dimensions var originalFile = Path.Combine(filepath, filename); var source = Image.FromFile(originalFile); if (source.Width <= thumbWi && source.Height <= thumbHi) return; Bitmap thumbnail; try { int wi = thumbWi; int hi = thumbHi; if (maintainAspect) { // Maintain the aspect ratio despite the thumbnail size parameters if (source.Width > source.Height) { wi = thumbWi; hi = (int)(source.Height * ((decimal)thumbWi / source.Width)); } else { hi = thumbHi; wi = (int)(source.Width * ((decimal)thumbHi / source.Height)); } } thumbnail = new Bitmap(wi, hi); 4.2. C# 137 Apuntes Informatica Documentation, Publicación 1.0.0 using (Graphics g = Graphics.FromImage(thumbnail)) { g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.FillRectangle(Brushes.Transparent, 0, 0, wi, hi); g.DrawImage(source, 0, 0, wi, hi); } var thumbnailName = Path.Combine(filepath, "thumbnail_" + filename); thumbnail.Save(thumbnailName); } catch { } } } } 4.3 MariaDB Categorias: 4.3.1 Claves Foráneas MariaDB Para la creación de las claves foráneas, existen 2 tablas, una tabla padre que es la que contiene un id único y una tabla que contiene un id que hace referencia a la clase padre. Nota: Me he dado cuenta que para que se pueda crear bien la foreign key, si la tabla padre la id es UNSIGNED la id hija ha de serlo también. -- Clase padre CREATE TABLE IF NOT EXISTS usuarios ( id_usr INT UNSIGNED NOT NULL AUTO_INCREMENT, nombre_usr VARCHAR(30) NOT NULL, PRIMARY KEY(id_usr) ) ENGINE = InnoDB; La clase hija tiene una id que hace referencia a la clase padre y no se podrá poner una id donde no exista en la clase padre. Las id ha de ser un tipo KEY/INDEX, PRIMARY KEY, etc, en caso de no existir a partir de MySQL 5 crea un index para las tablas. -- Clase hija CREATE TABLE IF NOT EXISTS comentarios ( id_cmt INT UNSIGNED NOT NULL AUTO_INCREMENT, id_usr INT UNSIGNED NOT NULL, comentario_cmt TEXT NOT NULL, PRIMARY KEY(id_cmt), INDEX(id_usr), FOREIGN KEY (id_usr) REFERENCES usuarios(id_usr) ON DELETE CASCADE ON UPDATE NO ACTION ) ENGINE = InnoDB; Las clases hijas son las que tienen la foreign key y hay dos formas de crear una foreign key, o bien dentro de la creación de la tabla 138 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 ( FOREIGN KEY (column_id) REFERENCES tabla_padre(column_id) ON DELETE CASCADE ON UPDATE NO ACTION ) o con ALTER TABLE: ALTER TABLE tabla_hija ADD CONSTRAINT FK_tabla_hija FOREIGN KEY (column_id) REFERENCES tabla_padre(column_id) ON UPDATE CASCADE ON DELETE RESTRICT; Donde CASCADE hay 4 tipos: [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}] CASCADE: Borra o actualiza el registro en la tabla padre y automáticamente borra o actualiza los registros coincidentes en la tabla hija. Tanto ON DELETE CASCADE como ON UPDATE CASCADE están disponibles en MySQL 5.0. Entre dos tablas, no se deberían definir varias cláusulas ON UPDATE CASCADE que actúen en la misma columna en la tabla padre o hija. SET NULL: Borra o actualiza el registro en la tabla padre y establece en NULL la o las columnas de clave foránea en la tabla hija. Esto solamente es válido si las columnas de clave foránea no han sido definidas como NOT NULL. MySQL 5.0 soporta tanto ON DELETE SET NULL como ON UPDATE SET NULL. NO ACTION: En el estándar ANSI SQL-92, NO ACTION significa ninguna acción en el sentido de que un intento de borrar o actualizar un valor de clave primaria no sera permitido si en la tabla reverenciada hay una valor de clave foránea relacionado. (Gruber, Mastering SQL, 2000:181). En MySQL 5.0, InnoDB rechaza la operación de eliminación o actualización en la tabla padre RESTRICT: Rechaza la operación de eliminación o actualización en la tabla padre. NO ACTION y RESTRICT son similares en tanto omiten la cláusula ON DELETE u ON UPDATE. (Algunos sistemas de bases de datos tienen verificaciones diferidas o retrasadas, una de las cuales es NO ACTION. En MySQL, las restricciones de claves foráneas se verifican inmediatamente, por eso, NO ACTION y RESTRICT son equivalentes.) SET DEFAULT: Esta acción es reconocida por el procesador de sentencias (parser), pero InnoDB rechaza definiciones de tablas que contengan ON DELETE SET DEFAULT u ON UPDATE SET DEFAULT. 4.3.2 Consulta fechas Consultas básicas de MySQL Comparar fechas, por ejemplo buscar usuarios que han nacido en un mes actual SELECT * FROM usuarios WHERE MONTH(fecha_nacimiento) = MONTH(CURDATE()); Con CURDATE() o NOW() dentro de MONTH(), DAYOFMONTH(), YEAR(), etc, compara una fecha pasada con la fecha actual. El libro de MySQL de Paul Dubois en la pagina 90+ muestra ejemplos de fechas. 4.3. MariaDB 139 Apuntes Informatica Documentation, Publicación 1.0.0 4.3.3 MariaDB Data Types Fuentes https://mariadb.com/kb/en/mariadb/mariadb-documentation/data-types/ http://www.techonthenet.com/mariadb/datatypes.php 4.3.4 Operador IN El operador IN() es util para cuando se buscan varios valores dentro de una consulta. La forma tradicional seria SELECT * FROM members WHERE id_member = '10' OR id_member = '20'; Lo que devolvería 2 usuarios, id 10 e id 20 Otra manera para hacerlo seria con IN() SELECT * FROM members WHERE id_member IN('10', '20'); 4.3.5 Ordenar Resultado Para la ordenación de resultados se hace con ORDER BY nombre_col ASC|DESC Para ordenar varios grupos ORDER BY col1 ASC, col2 DESC Lo que hace es ordenar col1 en ascendente y dentro de ese grupo, col2 lo ordena de manera descendente. 4.3.6 Poner password a un usuario desde la consola SET PASSWORD FOR 'user'@'localhost' = PASSWORD('pass'); Otra manera ya que los passwords y usuarios están en la tabla mysql.user seria UPDATE user SET user.Password = PASSWORD('123456') WHERE user.Host = 'localhost' AND user.User = 'nico'; Siempre y cuando el user sea nico y el host localhost Para ver todos los usuarios, host y si alguien no tiene pass: SELECT user.User, user.Host, user.Password FROM user; 140 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 4.3.7 Recuperar password root Fuentes http://www.guatewireless.org/os/linux/mysql-recuperar-la-contrasena-de-root-en-5-pasos/ /etc/init.d/mysql stop mysqld_safe --skip-grant-tables & mysql -u root use mysql; update user set password=PASSWORD("contraseña") where User='root'; flush privileges; quit /etc/init.d/mysql stop /etc/init.d/mysql start mysql -u root -p 4.4 PCRE - Perl Compatible Regular Expressions Categorias: 4.4.1 Caracteres con significado en PCRE Todos estos caracteres se han de escapar ya que tienen un significado especial. . \ + * ? [ ^ ] $ ( ) { } = ! < > | : 4.4.2 Detalles basicos en PCRE Fuentes http://es.php.net/manual/es/book.pcre.php http://www.php.net/manual/es/regexp.reference.meta.php http://www.php.net/manual/es/regexp.reference.escape.php#regexp.reference.escape Meta-caracteres (*) 0 o mas instancias de dicha expresión regular (|) Expresión regular compuesta por la expresión regular izquierda o derecha (^) Para identificar el inicio de una cadena ([^a-z]) Sirve para decir que no puede contener la expresión, en este caso cualquier letra en minúsculas. ($) Para identificar el final de una cadena (.) Para identificar la expresión “cualquier carácter” 4.4. PCRE - Perl Compatible Regular Expressions 141 Apuntes Informatica Documentation, Publicación 1.0.0 (+) Expresión regular compuesta por una o mas instancias de dicha expresión regular (?) Expresión regular compuesta por 0 o 1 instancia de dicha expresión regular ({max,min}) Expresión regular compuesta por un numero de variable de instancias de dicha Expresión Regular. El parámetro min indica el mínimo de numero de instancias aceptables, mientras que el parámetro max, si lo hubiera, indica el máximo numero de instancias aceptables. Si solo se encuentra min y la coma disponible, no existe ningún limite superior en cuanto al numero de instancias que podemos encontrar en la cadena. Por ultimo si solo definimos min sin la coma significara el único numero de instancias aceptable. ([]) Sirve para identificar grupos de caracteres aceptables para una determinada posición. Secuencias de escape (w) Representa un carácter de “palabra” y es equivalente a la expresión [a-zA-Z0-9_] (W) Representa lo opuesto a w y es equivalente a [^a-zA-Z0-9_] (s) Representa un carácter de espacio en blanco (S) Representa un carácter que no es un espacio en blanco (d) Representa un dígito, equivalente a [0-9] (D) Representa un carácter que no es un dígito, equivalente a [^0-9] (n) Representa un carácter de nueva linea (r) Representa un carácter de retorno de carro (t) Representa un carácter de tabulación 4.4.3 Verificacion de Email con PCRE PHP <?php $pattern = '/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' . '(([a-z0-9-])*([a-z0-9]))+(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i'; Python pattern = '{0}{1}'.format( r'^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*@([a-z0-9])', r'(([a-z0-9-])*([a-z0-9]))+(.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$') Javascript Advertencia: POR HACER 142 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 C# using System.Text.RegularExpressions; string pattern = @"^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])" + @"(([a-z0-9-])*([a-z0-9]))+(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$"; Regex regex = new Regex(pattern, RegexOptions.IgnoreCase); bool isValid = regex.IsMatch("snicoper@example.com"); HTML5 Advertencia: No probada ^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])(([a-z0-9-])*([a-z0-9]))+(\.([a-z0-9])([-a-z0-9_-]) 4.5 PostgreSQL Categorias: 4.5.1 PK, FK y UNIQUE Psql Fuentes http://www.postgresql.org/docs/9.3/static/ddl-constraints.html create table usuarios( id SERIAL, nombre VARCHAR(50) NOT NULL, password VARCHAR(40), CONSTRAINT pk_usuarios PRIMARY KEY(id) ); create table tablon_anuncios( id SERIAL, id_usuario INT NOT NULL, fecha INT NOT NULL DEFAULT EXTRACT(epoch from now()), titulo VARCHAR(255) NOT NULL, contenido text NOT NULL, CONSTRAINT pk_tablon_anuncios PRIMARY KEY(id_usuario), CONSTRAINT fk1_tablon_anuncios FOREIGN KEY(id_usuario) REFERENCES usuarios(id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE ); -- Crea la clave primaria de la tabla CONSTRAINT pk_tablon_anuncios PRIMARY KEY(id_usuario), -- Le dice, que la col id_usuario de la tabla tablon_anuncios 4.5. PostgreSQL 143 Apuntes Informatica Documentation, Publicación 1.0.0 -- es la foreign key, que usa como referencia la tabla usuarios -- col id CONSTRAINT fk1_tablon_anuncios FOREIGN KEY(id_usuario) REFERENCES usuarios(id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE -- unique CONSTRAINT unq_tablon_anuncios UNIQUE(nombre_tabla) 4.5.2 Comandos consola Postgres Nota: Cuando usa $, significa que esta en el shell, cuando no tiene nada es que esta en psql Login usuario postgres: $ sudo su - postgres Creación de un usuario: CREATE USER nombre_usuario WITH password '123456' Eliminar usuario: DROP USER nombre_usuario Crear base de datos: CREATE DATABASE nombre_db WITH OWNER nombre_usuario; Eliminar base de datos: DROP DATABASE nombre_db Acceder database con usuario x: psql -U nombre_usuario nombre_db Obtener ayuda: \h Quit \q Leer comandos desde un archivo: \i input.sql Dump db a un archivo: $ pg_dump -U nombre_usuario nombre_db > db.out Dump todas las bases de datos: $ sudo su - postgres $ pg_dumpall > /var/lib/pgsql/backups/dumpall.sql 144 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Restaurar db: $ sudo su - postgres $ psql -f /var/lib/pgsql/backups/dumpall.sql mydb Tambien: $ psql -U postgres nombredb < archivo_restauracion.sql List databases: \l List tables in database: \d Describe table: \d table_name Describe table: \d+ table_name Use database_name: \c nombre_db Show users: select * from "pg_user"; # tambien \du Escribir las consultas en tu editor favorito: \e Activar/Desactivar ver el tiempo del query: \timing Reset a user password as admin: ALTER USER usertochange WITH password 'new_passwd'; Select version SELECT version(); Change Database Owner: ALTER DATABASE database_name OWNER TO new_owner; Create a superuser user: ALTER USER mysuper WITH SUPERUSER; # or even better ALTER USER mysuper WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION Sabar el tamaño usado las tablas en una base de datos: Ver mas: http://www.niwi.be/2013/02/17/postgresql-database-table-indexes-size/ 4.5. PostgreSQL 145 Apuntes Informatica Documentation, Publicación 1.0.0 SELECT pg_size_pretty(pg_database_size('dbname')); 4.5.3 Crear Database Para crear una base de datos y poner como propietario a alguien: Nota: Crear User sudo -u postgres psql postgres CREATE DATABASE practicas WITH OWNER = snicoper; 4.5.4 Crear User Para crear un usuario: Nota: Crear Database sudo -u postgres psql postgres CREATE USER snicoper WITH PASSWORD '123456' NOCREATEDB NOCREATEUSER; 4.5.5 Duplicar tabla en postgresql Fuentes http://www.mkyong.com/database/postgresql-create-table-from-exisiting-table/ CREATE TABLE 'nombre_nueva_tabla' AS SELECT 'tabla_a_copiar'; Si la tabla tabla_a_copiar esta poblada y no deseamos copiar los datos existentes, se puede poner un WHERE en la consulta. CREATE TABLE 'nombre_nueva_tabla' AS SELECT 'tabla_a_copiar' WHERE 1 = 2; Como 1 no es igual a 2, no se insertara ningún dato de la 1º tabla. 4.5.6 Obtener ultimo ID insertado en la db INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John') RETURNING id Ejeplo con Python with psycopg2.connect(conn_string) as conn: with conn.cursor() as cur: cur.execute( "INSERT INTO persons(lastname, firstname) \ 146 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 VALUES(%s, %s) RETURNING id", (firstname, lastname)) conn.commit() print(cur.fetchone()[0]) 4.5.7 Reset Sequence ID Ejecutar pg_dump primero para no meter la pata. Se se han añadido y eliminado muchos campos y luego se quiere recuperar la secuencia del campo id en postgres. SELECT setval('table_name_id_seq', (SELECT MAX(id) FROM table_name)); Si se ha vaciado toda una tabla y se quiere resetear ALTER SEQUENCE table_name_id_seq RESTART; 4.6 Python Content: 4.6.1 Desordenar un string import random tamano = 10 abecedario = 'abcdefghijklmopqrstuvwxyz' desordenar = random.sample(abecedario, tamano) palabra = ''.join(desordenar) print(palabra) 4.6.2 Enviar email SMTP Fuentes http://www.mkyong.com/python/how-do-send-email-in-python-via-smtplib/ http://docs.python.org/3.3/library/smtplib.html import smtplib to = 'mkyong2002@yahoo.com' gmail_user = 'mkyong2002@gmail.com' gmail_pwd = 'yourpassword' smtpserver = smtplib.SMTP("smtp.gmail.com", 587) smtpserver.ehlo() smtpserver.starttls() smtpserver.ehlo smtpserver.login(gmail_user, gmail_pwd) header = 'To:' + to + '\n' + 'From: ' + gmail_user + '\n' + 'Subject:testing \n' 4.6. Python 147 Apuntes Informatica Documentation, Publicación 1.0.0 print header msg = header + '\n this is test msg from mkyong.com \n\n' smtpserver.sendmail(gmail_user, to, msg) print 'done!' smtpserver.close() 4.6.3 Ejemplo de comentarios en un archivo Python # -*- coding: utf-8 -*"""Example Google style docstrings. This module demonstrates documentation as specified by the `Google Python Style Guide`_. Docstrings may extend over multiple lines. Sections are created with a section header and a colon followed by a block of indented text. Example: Examples can be given using either the ``Example`` or ``Examples`` sections. Sections support any reStructuredText formatting, including literal blocks:: $ python example_google.py Section breaks are created by simply resuming unindented text. Section breaks are also implicitly created anytime a new section starts. Attributes: module_level_variable (int): Module level variables may be documented in either the ``Attributes`` section of the module docstring, or in an inline docstring immediately following the variable. Either form is acceptable, but the two should not be mixed. Choose one convention to document module level variables and be consistent with it. .. _Google Python Style Guide: http://google-styleguide.googlecode.com/svn/trunk/pyguide.html """ module_level_variable = 12345 def module_level_function(param1, param2=None, *args, **kwargs): """This is an example of a module level function. Function parameters should be documented in the ``Args`` section. The name of each parameter is required. The type and description of each parameter is optional, but should be included if not obvious. If the parameter itself is optional, it should be noted by adding ", optional" to the type. If \*args or \*\*kwargs are accepted, they should be listed as \*args and \*\*kwargs. The format for a parameter is:: name (type): description 148 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 The description may span multiple lines. Following lines should be indented. Multiple paragraphs are supported in parameter descriptions. Args: param1 (int): The first parameter. param2 (str, optional): The second parameter. Defaults to None. Second line of description should be indented. args: Variable length argument list. * **kwargs: Arbitrary keyword arguments. Returns: bool: True if successful, False otherwise. The return type is optional and may be specified at the beginning of the ``Returns`` section followed by a colon. The ``Returns`` section may span multiple lines and paragraphs. Following lines should be indented to match the first line. The ``Returns`` section supports any reStructuredText formatting, including literal blocks:: { 'param1': param1, 'param2': param2 } Raises: AttributeError: The ``Raises`` section is a list of all exceptions that are relevant to the interface. ValueError: If `param2` is equal to `param1`. """ if param1 == param2: raise ValueError('param1 may not be equal to param2') return True def example_generator(n): """Generators have a ``Yields`` section instead of a ``Returns`` section. Args: n (int): The upper limit of the range to generate, from 0 to `n` - 1 Yields: int: The next number in the range of 0 to `n` - 1 Examples: Examples should be written in doctest format, and should illustrate how to use the function. >>> print [i for i in example_generator(4)] [0, 1, 2, 3] """ 4.6. Python 149 Apuntes Informatica Documentation, Publicación 1.0.0 for i in range(n): yield i class ExampleError(Exception): """Exceptions are documented in the same way as classes. The __init__ method may be documented in either the class level docstring, or as a docstring on the __init__ method itself. Either form is acceptable, but the two should not be mixed. Choose one convention to document the __init__ method and be consistent with it. Note: Do not include the `self` parameter in the ``Args`` section. Args: msg (str): Human readable string describing the exception. code (int, optional): Error code, defaults to 2. Attributes: msg (str): Human readable string describing the exception. code (int): Exception error code. """ def __init__(self, msg, code=2): self.msg = msg self.code = code class ExampleClass(object): """The summary line for a class docstring should fit on one line. If the class has public attributes, they should be documented here in an ``Attributes`` section and follow the same formatting as a function's ``Args`` section. Attributes: attr1 (str): Description of `attr1`. attr2 (list of str): Description of `attr2`. attr3 (int): Description of `attr3`. """ def __init__(self, param1, param2, param3=0): """Example of docstring on the __init__ method. The __init__ method may be documented in either the class level docstring, or as a docstring on the __init__ method itself. Either form is acceptable, but the two should not be mixed. Choose one convention to document the __init__ method and be consistent with it. Note: Do not include the `self` parameter in the ``Args`` section. Args: param1 (str): Description of `param1`. param2 (list of str): Description of `param2`. Multiple 150 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 lines are supported. param3 (int, optional): Description of `param3`, defaults to 0. """ self.attr1 = param1 self.attr2 = param2 self.attr3 = param3 def example_method(self, param1, param2): """Class methods are similar to regular functions. Note: Do not include the `self` parameter in the ``Args`` section. Args: param1: The first parameter. param2: The second parameter. Returns: True if successful, False otherwise. """ return True def __special__(self): """By default special members with docstrings are included. Special members are any methods or attributes that start with and end with a double underscore. Any special member with a docstring will be included in the output. This behavior can be disabled by changing the following setting in Sphinx's conf.py:: napoleon_include_special_with_doc = False """ pass def __special_without_docstring__(self): pass def _private(self): """By default private members are not included. Private members are any methods or attributes that start with an underscore and are *not* special. By default they are not included in the output. This behavior can be changed such that private members *are* included by changing the following setting in Sphinx's conf.py:: napoleon_include_private_with_doc = True """ pass def _private_without_docstring(self): 4.6. Python 151 Apuntes Informatica Documentation, Publicación 1.0.0 pass 4.6.4 hashlib Fuentes https://docs.python.org/3.4/library/hashlib.html Ejemplo rapido from hashlib import sha256 a = sha256() a.update(b'123456') password = a.hexdigest() # Si el password es pasado en una variable mi_password = '123456' a = sha256() a.update(mi_password.encode('utf-8')) password = a.hexdigest() 4.6.5 Pickle serialize database Serializa datos y los guarda en una base de datos. Base de datos para el ejemplo CREATE TABLE datas ( id serial NOT NULL, data_serializada text NOT NULL, CONSTRAINT pk_id_datas PRIMARY KEY (id) ) Ejemplo serializando un único objeto import pickle import psycopg2 conn_string = 'dbname=practicas \ user=snicoper \ password=123456' class Persona(object): def __init__(self, nombre, apellidos, email): self.nombre = nombre self.apellidos = apellidos self.email = email persona = Persona('salvador', 'nicolas pereiro', 'snicoper@example.com') # Guardar los datos en la db, pasar de bytes a str 152 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 data = pickle.dumps(persona, 0) data = data.decode('utf-8') with psycopg2.connect(conn_string) as conn: with conn.cursor() as cur: cur.execute( "INSERT INTO datas(data_serializada) \ VALUES(%s)", (data,)) conn.commit() # Leer los datos with psycopg2.connect(conn_string) as conn: with conn.cursor() as cur: cur.execute( "SELECT * FROM datas WHERE id = 1") datas = cur.fetchone() # pasar de str a bytes datas = datas[1].encode('utf-8') p = pickle.loads(datas) print(p.nombre) Ejemplo serializando varios objetos a la vez persona = Persona('salvador', 'nicolas pereiro', 'snicoper@example.com') persona2 = Persona('perico', 'palote', 'perico@example.com') # Guardar los datos en la db, pasar de bytes a str data = pickle.dumps((persona, persona2), 0) data = data.decode('utf-8') with psycopg2.connect(conn_string) as conn: with conn.cursor() as cur: cur.execute( "INSERT INTO datas(data_serializada) \ VALUES(%s) RETURNING id", (data,)) conn.commit() last_id = cur.fetchone()[0] # Leer los datos with psycopg2.connect(conn_string) as conn: with conn.cursor() as cur: cur.execute( "SELECT * FROM datas \ WHERE id=%s", (last_id,)) datas = cur.fetchone() # pasar de str a bytes datas = datas[1].encode('utf-8') p1, p2 = pickle.loads(datas) print(type(p2)) 4.6.6 Obtener diccionario de una consulta sql Fuentes http://stackoverflow.com/questions/16519385/output-pyodbc-cursor-results-as-python-dictionary 4.6. Python 153 Apuntes Informatica Documentation, Publicación 1.0.0 cursor = connection.cursor() cursor.execute(sql) columns = [column[0] for column in cursor.description] results = [] for row in cursor.fetchall(): results.append(dict(zip(columns, row))) print(results) 4.6.7 Leer y guardar datos json en la db Leer y guardar datos JSON en una base de datos con psycopg2. El ejemplo es muy simple, pero para una rápida referencia, lo guardo. import json import psycopg2 def connect(): conn = psycopg2.connect(" \ dbname=practicas \ user=snicoper \ password=123456") return conn def save_data(data): conn = connect() cursor = conn.cursor() cursor.execute('insert into datas(data) values(%s)', (data,)) conn.commit() conn.close() def load_data(id): conn = connect() cursor = conn.cursor() cursor.execute('SELECT * FROM datas WHERE id = %s', (id, )) datos = cursor.fetchone() conn.close() return datos # Guardar en la db archivo_json = 'tests/datas.json' json_datas = open(archivo_json) data = json.load(json_datas) print(json.dumps(data)) save_data(json.dumps(data)) json_datas.close() # Leer desde la db datos = load_data(3)[1] datos_json = json.loads(datos) print(datos_json['nombre']) 154 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 4.6.8 Redimensionar imagen import os from PIL import Image def resize_image(image_path, save_path, base_width, base_height, scale=True, prefix_name=None): """Redimensiona una imagen. Redimensiona una imagen a base_width y base_height, si scale es True, base_height redimensionara a escala de base_width. Si la base_width y base_height es mayor a la imagen original, dejara el tamaño original. args: image_path<str>: Path de la imagen a redimensionar. base_width<float|int>: Ancho maximo. base_height<float|int>: Alto maximo. scale<bool>: ¿Mantener proporcion?. prefix_name<str>: Prefijo en el nombre de la imagen, no añadir el caracter '_'. raises: FileNotFoundError: Si no existe image_path. @return: void """ if not os.path.exists(image_path): raise FileNotFoundError('La imagen {} no existe'.format(image_path)) if prefix_name: basename = '{}_{}'.format(prefix_name, os.path.basename(save_path)) dirname = os.path.dirname(save_path) save_path = os.path.join(dirname, basename) img = Image.open(image_path) img_width, img_height = float(img.size[0]), float(img.size[1]) if img_width <= base_width and img_height <= base_height: img.save(save_path) else: width = base_width height = base_height if scale: if img_width > img_height or img_width == img_height: width = base_width height = int(img_height * (base_width / img_width)) else: height = base_height width = int(img_width * (base_height / img_height)) img = img.resize((width, height), Image.ANTIALIAS) img.save(save_path) Categorias 4.6.9 Django Apps: 4.6. Python 155 Apuntes Informatica Documentation, Publicación 1.0.0 Apps Apps: Django Authentication Configuraciones En src/config/settings/base.py AUTHENTICATION_TYPE: both, username o email, por defecto both AUTH_REGISTER_EXPIRE_DAYS: días antes de expirar los registros temporales por defecto 1 Requiere configruacion SMTP, cambiar valores de: EMAIL_USE_TLS = True EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT = '587' EMAIL_HOST_USER = 'user@gmail.com' EMAIL_HOST_PASSWORD = 'password_gmail' Migración e iniciar Desde un entorno virtual pip install -r requirements/local.txt ./manage.py migrate ./manage.py createsuperuser # opcional ./manage.py runserver http://127.0.0.1:8000 Django templateforms Templates para [Materializecss](http://materializecss.com), pero facilmente se pueden añadir para otros frameworks css. Uso Cargar las tags al principio del template. {% load templateforms %} La manera mas rápida de usarla es con el tag form pasando como parámetro el formulario. <form method="post" action=""> {% csrf_token %} {% form form %} <button type="submit">Submit</button> </form> Si se quiere omitir el * cuando el campo es requerido { % form form hidden_required=’1’ %} <form method="post" action=""> {% csrf_token %} {% form form hidden_required='1' %} <button type="submit">Submit</button> </form> 156 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Campo a campo Otra manera es pasando cada campo del formulario, pudiendo pasar parámetros. <form method="post" action=""> {% csrf_token %} {# Mostrar errores globales del formulario #} {% non_field_errors form.non_field_errors %} {# Campos ocultos #} {% form_hidden_fields form.hidden_fields %} {# Campos del formulario #} {% form_field form.myfield label='My Field' extras='placeholder="My Placeholder"' %} <button type="submit">Submit</button> </form> Parámetros Globales Estos parámetros los acepta todos los campos. col: Es el campo col en materializecss <div class="row"> <!-- Materializecss --> {% form_field form.myfield col='s12 m12 l6' %} </div> Pondrá en large un campo al lado del otro. Requiere envolverlo en un div (u otro contenedor) con class="row". Si se omite, envolverá internamente el campo en un <div class="row"><div class="col s12">. tpl_name: Omite el template del tipo de campo por defecto. {% form_field form.myfield tpl_name='mistemplates/mitemplate.html' %} klass: Clases a insertar en el campo. {% form_field form.myfield klass='miclass miclass2' %} {# Sera rempladado por #} <input|select|textarea| class="miclass miclass2" ...> extras: Propiedades extras que se añadirán. {% form_field form.myfield extras='ng-model="mimodel" otras="xxx"' %} {# Sera rempladado por #} <input|select|textarea| ng-model="mimodel" otras="xxx" ...> label: Nombre a mostrar {% form_field form.myfield label="Mi label personalizado" %} Si se omite, usara form.myfield.label Todos los campos añade el valor de help_text del model o form, si lo tiene. <span class="help_text">{{ field.help_text }}</span> Todos los campos añade {{ field.errors }} (es el de django por defecto) 4.6. Python 157 Apuntes Informatica Documentation, Publicación 1.0.0 <ul class="errorlist"><li>This field is required.</li></ul> Type text Los campos de tipo texto como text, email, number, date, password, url, etc, aceptan los siguientes parámetros. ftype: Para cambiar el type="", por defecto text Internamente, ya añade un type adecuado, pero si algún campo no lo he puesto, es posible ponerlo desde estos parámetros. img: Añade una imagen a la izquierda del campo (materializecss). Requiere las fuentes de material icons <!-- en base.html --> <link rel="stylesheet" href="http://fonts.googleapis.com/icon?family=Material+Icons"> <!-- en cualquier plantilla donde se este creando el form --> {% form_field form.myfield img="account_circle" %} Cualquier imagen de [material icons](https://design.google.com/icons/) pasando el en nombre. No incluye ningun Javascript, por lo que si el campo lo require, se debera añadir a parte, como por ejemplo los campos select $(document).ready(function() { $('select').material_select(); }); ImageField FileField En primer en el directorio donde tengo los test_xxx.py pongo una imagen que sirva para las pruebas. Pongo en algún sitio de los test (compartido) images.py y dentro: from django.core.files.uploadedfile import SimpleUploadedFile def simple_uploaded_file(image_path): """Crea una SimpleUploadedFile para campos de modelo ImageField, FileField. Args: image_path (str): Path de la imagen a "subir". Returns: SimpleUploadedFile: """ if not os.path.exists(image_path): raise FileNotFoundError('El "{}" archivo no existe'.format(image_path)) name = os.path.basename(image_path) with open(image_path, 'rb') as fh: image = SimpleUploadedFile( name=name, content=fh.read(), content_type='image/jpeg' ) return image 158 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Ahora, en el inicio del archivo (antes de cualquier clase): image_path = os.path.join(os.path.dirname(__file__), 'image_test.jpg') Y ahora, dentro del una clase test, en setUp def setUp(self): super().setUp() self.image = simple_uploaded_file(image_path) Hay que procurar eliminar siempre la imagen. Unit Test Solucion para el error django.contrib.messages.middleware.MessageMiddleware Fuentes http://stackoverflow.com/questions/11938164/why-dont-my-django-unittests-know-that-messagemiddlewareis-installed raise MessageFailure('You cannot add messages without installing ' django.contrib.messages.api.MessageFailure: You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware Cuando en la view crea un django.contrib.messages, con en UnitTest me da un error cuando accedo con RequestFactory, para solucionarlo. from django.contrib.messages.storage.fallback import FallbackStorage setattr(request, 'session', 'session') messages = FallbackStorage(request) setattr(request, '_messages', messages) Ejemplo mas largo. def test_send_mail(self): """ Manda un email cuando se ha completado el formulario. """ form_data = { 'email': 'test@example.com', 'subject': 'test subject', 'message': 'test test test' } request = self.factoty.post(reverse('contact.contact'), data=form_data) # http://stackoverflow.com/questions/11938164/ # why-dont-my-django-unittests-know-that-messagemiddleware-is-installed from django.contrib.messages.storage.fallback import FallbackStorage setattr(request, 'session', 'session') messages = FallbackStorage(request) setattr(request, '_messages', messages) # ----- # request.user = self.user ContactView.as_view()(request) self.assertEqual(len(mail.outbox), 1) Categorias: 4.6. Python 159 Apuntes Informatica Documentation, Publicación 1.0.0 Insertar atributos en todos los campos en un ModelForm Para poder insertar un atributo en todos los campos de un formulario, por ejemplo el class="form-control" y no estar haciéndolo de uno a uno en todos sus campos. from django import forms from .models import IceCreamStore class IceCreamStoreForm(forms.ModelForm): class Meta: model = IceCreamStore def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for field in self.fields: # Recorremos todos los campos del modelo para añadirle class="form-control self.fields[field].widget.attrs.update({'class': 'form-control'}) # Añadir atributos personalizados a campos sueltos. self.fields['title'].widget.attrs.update({'placeholder': 'Titulo'}) Cambiar el nombre en la cabecera de la administración El el URLConf principal myproject/urls.py añadir from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), ] # Añadir admin.site.site_header = 'Nuevo nombre' CBV login_required from django.contrib.auth.decorators import login_required from django.utils.decorators import method_decorator from django.views import generic class LoggedInMixin(object): @method_decorator(login_required) def dispatch(self, *args, **kwargs): return super(LoggedInMixin, self).dispatch(*args, **kwargs) # views.py class UpdateContactView(LoggedInMixin, generic.UpdateView): pass A partir de Django 1.9 160 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 # views.py from django.contrib.auth.mixins import LoginRequiredMixin from django.views import generic class UpdateContactView(LoginRequiredMixin, generic.UpdateView): pass Tambien pueda interesar django-braces Concatenar un valor en settings.py Fuentes http://stackoverflow.com/questions/2246725/django-template-context-processors Por ejemplo, para añadir en TEMPLATE_CONTEXT_PROCESSORS django.core.context_processors.request dentro de settings.py el request from django.conf import global_settings TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + ( 'django.core.context_processors.request', ) Permiso crear db en tests Simplemente, el usuario ha de tener permisos para poder crear bases de datos. En postgres: ALTER USER snicoper CREATEDB; Django markdown pip install markdown2 Crear un template filter # filters_tags.py import markdown2 from django import template from django.utils.safestring import mark_safe @register.filter('markdown') def markdown_format(text): """Devuelve el texto markdown en HTML. Args: text str: Texto markdown Returns: str El markdown convertido en HTML. """ return mark_safe(markdown2.markdown(text)) 4.6. Python 161 Apuntes Informatica Documentation, Publicación 1.0.0 Desde un template .html {% load filters_tags %} {{ article.body|markdown }} Django Markdown y Google Prettify Fuentes https://github.com/timmyomahony/django-pagedown https://github.com/trentm/django-markdown-deux https://code.google.com/p/google-code-prettify/wiki/GettingStarted Una manera rápida para añadir entradas con markdown y/o resaltar bloques de código. Mientras que django-pagedown lo uso para mostrar el <textarea> con algunos botones de ayuda para formatear el codigo markdown, django-markdown-deux lo utilizo la presentación (formateado). Y por ultimo, utilizo google-code-prettify para el resaltado de sintaxis. Instalación: pip install django-pagedown pip install django-markdown-deux Añadir en settings.py INSTALLED_APPS = ( # [...] 'markdown_deux', 'pagedown', ) django-pagedown Todos los TextField de un modelo. Añadir en admin.py: from django.contrib import admin from django.db import models from pagedown.widgets import AdminPagedownWidget from .models import Article class ArticleAdmin(admin.ModelAdmin): formfield_overrides = { models.TextField: {'widget': AdminPagedownWidget}, } admin.site.register(Article, ArticleAdmin) Ver todas las opciones django-pagedown 162 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 django-markdown-deux Para la presentación y formateo de marcado. Añado en el template que mostrara el código markdown {% extends 'base.html' %} {% load markdown_deux_tags %} {% block content %} <h2>{{ article.title }}</h2><hr> <div> {{ article.body|markdown }} </div> {% endblock content %} Ver todas las opciones django-markdown-deux google-code-prettify Descargar y descomprimir prettify-small-4-Mar-2013.tar.bz2 o la versión mas reciente. Renombro google-code-prettify a prettify y la pego en project_dajngo/static/js/. Entro dentro de project_dajngo/static/js/prettify/, corto prettify.css y pego en project_dajngo/static/css/. Añado en la parte del css. <link href="{% static "css/prettify.css" %}" rel="stylesheet"> y en la parte del javascript. <script src="{% static "js/prettify/prettify.js" %}"></script> <script type='text/javascript'> $('pre').addClass('prettyprint'); prettyPrint(); </script> Algunos themes para prettify http://demo.stanleyhlng.com/prettify-js/?id=bootstrap-light http://jmblog.github.io/color-themes-for-google-code-prettify/ Scroll si el código es muy largo, en el archivo .css pre code { overflow: auto; display: block; line-height: 1.6em; white-space: pre; word-wrap: normal; /* Si se quiere poner un height maximo */ /*max-height: 600px;*/ } Números en las lineas, modificar $(’pre’).addClass(’prettyprint’); $(’pre’).addClass(’prettyprint linenums’); por Otra opción para el resaltado de sintaxis highlight.js 4.6. Python 163 Apuntes Informatica Documentation, Publicación 1.0.0 Django y MSSQL Fuentes https://django-mssql.readthedocs.org/en/latest/index.html https://bitbucket.org/Manfre/django-mssql http://sourceforge.net/projects/pywin32/ Probado con sqlexpress 2014, python 3.4.2 x64, Windows 8.1 pip install django-mssql Descargar el .exe de pywin32 según versión y arquitectura Yo lo instalo con virtualenv, supongo que si se hace en el python principal, doble click, siguiente, siguiente... # Con virtualenv cd ~/Downloads easy_install pywin32-219.win-amd64-py3.4.exe Configuración de settings.py DATABASES = { 'default': { 'NAME': 'django', 'ENGINE': 'sqlserver_ado', 'HOST': r'.\SQLEXPRESS', 'USER': 'snicoper', 'PASSWORD': '123456', 'OPTIONS': { 'provider': 'SQLNCLI11', }, } } Django signals Referencias https://docs.djangoproject.com/en/1.8/ref/signals/ http://www.koopman.me/2015/01/django-signals-example/ http://www.snicoper.com/blog/article/signals-en-django/ Para un pequeño ejemplo, vamos a crear un modelo UserProfile con la información del usuario. Vamos a añadir los campos pais y provincia y un campo user que tendrá una relación OneToOneField con settings.AUTH_USER_MODEL. En este caso, se supone que se usara después de que el usuario haya sido creado, pero no la mostrara en el formulario de registro, por eso, los campos pais y provincia serán default=’’, blank=True (blank=True, ya va a gustos si cuando muestre el formulario, es requerido o no). 164 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 # accounts/models.py from django.db import models from django.conf import settings class UserProfile(models.Model): user = models.OneToOneField( settings.AUTH_USER_MODEL, primary_key=True, related_name='user_profile' ) pais = models.CharField(max_length=100, default='', blank=True) provincia = models.CharField(max_length=100, default='', blank=True) # Otros campos... Ahora, podemos hacelo de dos maneras, una añadiendo el signal en el mismo modulo del modelo, o bien creando un modulo separado signals.py. Para crearlo en el mismo modulo models.py, creamos el signal abajo del archivo. # accounts/models.py # Importar los modulos necesarios al principio. from django.db.models.signals import post_save from django.dispatch import receiver from django.conf import settings @receiver(post_save, sender=settings.AUTH_USER_MODEL) def create_profile_handler(sender, instance, created, **kwargs): if not created: return UserProfile.objects.create(user=instance) Cada vez que se cree, un usuario, se creara un campo en el modelo UserProfile. Esta es la manera rápido, pero si hay muchos signals lo ideal es ponerlos todos juntos en el modulo signals. # accounts/signals.py from django.db.models.signals import post_save from django.dispatch import receiver from django.conf import settings @receiver(post_save, sender=settings.AUTH_USER_MODEL) def create_profile_handler(sender, instance, created, **kwargs): if not created: return UserProfile.objects.create(user=instance) De momento, no hemos hecho nada nuevo..., creamos un modulo apps.py y añadimos. # accounts/apps.py from django.apps import AppConfig class AccountsConfig(AppConfig): name = 'accounts' verbose_name = 'Accounts Application' def ready(self): from . import signals Donde name = ’accounts’ es la ruta a la app, si estuviera en apps/accounts, se tendria que cambiar por name = ’apps.accounts’, verbose_name es un nombre legible que le damos. 4.6. Python 165 Apuntes Informatica Documentation, Publicación 1.0.0 Con esto, cada vez que se cree un nuevo usuario en la base de datos, se creara una fila en la table accounts_userprofile con un campo relacional a auth_user (por defecto). loaddata y dumpdata Fuentes https://coderwall.com/p/mvsoyg/django-dumpdata-and-loaddata loaddata ./manage.py loaddata filename.json dumpdata Toda la base de datos ./manage.py dumpdata > db.json Una app especifica ./manage.py dumpdata admin > admin.json Una tabla especifica ./manage.py dumpdata auth.user > user.json Indentacion en el archivo ./manage.py dumpdata auth.user --indent 2 > user.json Generar un slug automaticamente Con django # myapp/models.py from django.core.urlresolvers import reverse from django.db import models from django.template.defaultfilters import slugify class Noticia(models.Model): titulo = models.CharField(max_length=200) slug = models.CharField(max_length=200, blank=True) def save(self, *args, **kwargs): self.slug = slugify(self.titulo) super(Noticia, self).save(*args, **kwargs) Manualmente 166 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 # myapp/models.py import re from django.core.urlresolvers import reverse from django.db import models class Noticia(models.Model): titulo = models.CharField(max_length=200) slug = models.CharField(max_length=200, blank=True) def save(self, *args, **kwargs): self.slug = re.sub(r'[^a-z0-9+]', '-', self.titulo.lower()) super(Noticia, self).save(*args, **kwargs) https://docs.djangoproject.com/en/1.7/ref/contrib/admin/#django.contrib.admin.ModelAdmin.prepopulated_fields # myapp/admin.py from django.contrib import admin from .models import Noticia class NoticiaAdmin(admin.ModelAdmin): prepopulated_fields = {'slug': ('titulo',)} admin.site.register(Noticia, NoticiaAdmin) Generar un Token django.utils.crypto.get_random_string from django.utils.crypto import get_random_string token = get_random_string(length=30) Argumentos por defecto: length=12 allowed_chars=’abcdefghijklmnopqrstuvwxyz’ ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789’ Otra opción import hashlib import random def generate_token(length=12): """Genera un token único de 30 caracteres como máximo.""" chars = list( 'ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwyz01234567890' ) random.shuffle(chars) chars = ''.join(chars) sha1 = hashlib.sha1(chars.encode('utf8')) token = sha1.hexdigest() return token[:length] 4.6. Python 167 Apuntes Informatica Documentation, Publicación 1.0.0 Otra opción import uuid def generate_token(): """Genera un token unico de 32 caracteres.""" return str(uuid.uuid4()).replace('-', '') Generar gráficos del modelo con django-extensions Para crear una representación gráfica de lo modelos, hay que tener instalado django-extensions. Prerequisitos Se ha de instalar el paquete graphviz, en Fedora: sudo dnf install graphviz graphviz-devel Ahora en el entorno virtual (por ejemplo), instalar django-extensions y pygraphviz. (my_venv) pip install django-extensions pygraphviz Añadimos django-extensions en INSTALLED_APPS. # my_project/settings.py INSTALLED_APPS = ( # ... 'django-extensions', ) Ahora, para generar las imágenes, de todos los modelos, incluidos los propios de Django: ./manage.py graph_models -a -o myapp_models.png Y para generar de modelos específicos: ./manage.py graph_models myapp1 myapp2 > models.dot dot -Tpng models.dot -o models.png Cómo crear archivos de idioma Fuentes https://docs.djangoproject.com/en/1.7/topics/i18n/translation/ http://www.i18nguy.com/unicode/language-identifiers.html http://django-book.readthedocs.org/en/latest/chapter19.html Es posible hacerlo de dos maneras diferentes. Desde la raíz del proyecto Django, donde esta manage.py o desde la raíz de la app. Desde la raíz del proyecto 168 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Hay que editar settings.py para decirle los módulos que tendrán traducciones. LOCALE_PATHS = ( os.path.join(BASE_DIR, 'apps/home/locale/'), ) Después, ejecutar ./manage.py makemessages -l es Donde es es el identificador de lenguaje, aqui una lista Desde la raíz de la app Aquí no es necesario añadir LOCALE_PATHS a settings.py, y en vez de usar manage.py, se usa django-admin.py, además el directorio locale se ha de crear a mano. cd myapp mkdir locale django-admin.py makemessages -l es El script recorre completamente el árbol en el cual es ejecutado y extrae todas las cadenas marcadas para traducción. Crea (o actualiza) un archivo de mensajes en el directorio locale. En el ejemplo es, el archivo será locale/de/LC_MESSAGES/django.po. Dentro de los archivos .po, se va algo así. #: views.py:6 msgid "name" msgstr "nombre" msgid es la cadena de traducción, la cual aparece en el código fuente. No la modifiques. msgstr es donde colocas la traducción específica a un idioma. Su valor inicial es vacío de manera que es tu responsabilidad el cambiar esto. Asegúrate de que mantienes las comillas alrededor de tu traducción. Por conveniencia, cada mensaje incluye el nombre del archivo y el número de línea desde el cual la cadena de traducción fue extraída. #... from django.utils.translation import gettext_lazy as _ def index(request): var_name = _('name') #... el valor de var_name sera nombre Después, hay que compilarlo con compilemessages, y se aplica lo mismo que antes, cuando se hizo desde la raiz del proyecto Django o desde la raíz de la aplicación. # desde la raíz del proyecto ./manage.py compilemessages # desde la raíz de la aplicacion django-admin.py compilemessages Para reexaminar todo el código fuente y las plantillas en búsqueda de nuevas cadenas de traducción y actualizar todos los archivos de mensajes para todos los idiomas, ejecuta lo siguiente: 4.6. Python 169 Apuntes Informatica Documentation, Publicación 1.0.0 ./manage.py/django-admin.py makemessages -a Algunas notas Para configurar una preferencia de idioma a nivel de la instalación, fija LANGUAGE_CODE en tu archivo de configuración. Django usará este idioma como la traducción por omisión – la opción a seleccionarse en último término si ningún otro traductor encuentra una traducción. Si deseas permitir que cada usuario individual especifique el idioma que ella o él prefiere, usa LocaleMiddleware. LocaleMiddleware permite la selección del idioma basado en datos incluidos en la petición. Personaliza el contenido para cada usuario. Para usar LocaleMiddleware, agrega django.middleware.locale.LocaleMiddleware a tu variable de configuración MIDDLEWARE_CLASSES. Debido a que el orden de los middlewares es rele- vante, deberías seguir las siguientes guías: Asegúrate de que se encuentre entre las primeras clases middleware instaladas. Debe estar ubicado después de SessionMiddleware, esto es debido a que LocaleMiddleware usa datos de la sesión. Si usas CacheMiddleware, coloca LocaleMiddleware después de este (de otra forma los usuarios podrían recibir contenido cacheado del locale equivocado). LocaleMiddleware intenta determinar la preferencia de idioma del usuario siguiendo el siguiente algoritmo: Primero, busca una clave django_language en la sesión del usuario actual. Se eso falla, busca una cookie llamada django_language. Si eso falla, busca la cabecera HTTP Accept-Language. Esta cabecera es enviada por tu nave- gador y le indica al servidor qué idioma(s) prefieres en orden de prioridad. Django intenta con cada idioma que aparezca en dicha cabecera hasta que encuentra uno para el que haya disponible una traducción. Si eso falla, usa la variable de configuración global LANGUAGE_CODE. Importar configuracion django en archivo python import os os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nombre_proyecto.settings') import django django.setup() from my_app.models import MiModel1, MiModel2 # .... Template tags y filter personalizados Fuentes https://docs.djangoproject.com/es/1.10/howto/custom-template-tags/ A veces, va bien crear plantillas base que importan datos y mostrarlos, por ejemplo un menú lateral con categorías, pero que solo es útil para la app X. 170 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Para no estar mandando esos mismos datos desde las vistas a los templates desde todas las vista, una manera mas rápida y sencilla, es creándolas con template tags. Para el ejemplo, tenemos un modelo muy simple. class Category(models.Model): name = models.CharField(max_length=254) # [...] La platilla blog/_categories.html <ul> {% for cat in categories %} <li>{{ cat.name }}</li> {% endfor %} </ul> Dentro de la app creamos una carpeta con el nombre templatetags y dentro de templatetags un archivo __init__.py y por ultimo un archivo donde irán los template tags con el nombre blog_tags. from django import template from ..models import Category register = template.Library() @register.inclusion_tag('blog/_categories.html') def get_category_list(): return {'categories': Category.objects.all()} Y ahora, cada vez que queramos mostrar (importar), el trozo de código de blog/_categories.html, tendremos que hacer uso de load en cualquier template de nuestro sitio. <!-- Añadir load antes de llamar a get_category_list --> {% load blog_tags %} <!-- Y ahora, en la parte que se necesite blog/_categories.html {% get_category_list %} --> También es posible pasar parámetros, para verlos, mirar las fuentes. Crear un archivo en templatetags con un nombre form_helper_tags o similar e introducir: import re from django import template from django.utils.safestring import mark_safe register = template.Library() @register.filter def add(html_input, properties): """ Inserta propiedades en un campo html. Uso: {{ form.field_name|add:'class="form-control" placeholder="Placeholder here"' }} """ pattern = r'(\s\/>|>)' 4.6. Python 171 Apuntes Informatica Documentation, Publicación 1.0.0 regex = re.compile(pattern, re.IGNORECASE) replace = ' {0}>'.format(properties) html = regex.sub(replace, str(html_input)) return mark_safe(html) Para usar, desde el template html {% load form_helper_tags %} # ... <div class="form-group"> {{ form.field_name.label_tag }} {{ form.field_name|add:'class="form-control" placeholder="Placeholder here"' }} </div> # ... Login con username o email Con este pequeño tip, vamos a permitir que un usuario pueda loguearse poniendo el email y/o username y contraseña. En el archivo de configuración settings.py vamos a crear una variable AUTH_AUTHENTICATION_TYPE con uno de los siguientes valores: both, email, username. Ademas, tenemos que cambiar el valor de AUTHENTICATION_BACKENDS. El valor es una lista o tupla con los backends de autenticación, valga la redundancia. settings.py AUTH_AUTHENTICATION_TYPE = 'both' AUTHENTICATION_BACKENDS = ( 'accounts.backends.EmailOrUsernameModelBackend', ) Se entiende que tenemos la app accounts y dentro de ella, creamos el archivo backends.py. Dentro de backends.py añadimos: from from from from django.conf import settings django.contrib.auth import get_user_model django.contrib.auth.backends import ModelBackend django.db.models import Q class EmailOrUsernameModelBackend(ModelBackend): def authenticate(self, username=None, password=None): auth_type = settings.AUTH_AUTHENTICATION_TYPE if auth_type == 'username': return super().authenticate(username, password) user_model = get_user_model() try: if auth_type == 'both': user = user_model.objects.get( Q(username__iexact=username) | Q(email__iexact=username) ) else: user = user_model.objects.get(email__iexact=username) if user.check_password(password): 172 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 return user except user_model.DoesNotExist: return None Ahora iniciando el servidor, puedes jugar un poco y ver los resultados http://127.0.0.1:8000/admin/ Marcar active pagina actual en templates Crear en la app core un directorio template_tags con su __init__.py. Crear el archivo core_tags.py y añadir: from django.template import Library from django.core.urlresolvers import reverse register = Library() @register.simple_tag def active_link(request, urlconf_name): """Devolvera active si request.path coincide con reverse(urlconf_name), en caso contrario devolvera ''. """ url_reverse = reverse(urlconf_name) if request.path == url_reverse: return 'active' return '' Para usarlo en el template, en el link que se quiere comprobar: <li class="{% active_link request 'home_page' %}"> <a href="{% url 'home_page' %}">Home</a> </li> Nombre de la tag active_link, el objeto request y el nombre en URLConf completo, igual que se hace en un link { % url ’home:index’ %}. Migraciones en Django 1.7+ Crear migraciones ./manage.py makemigrations polls Mediante la ejecución de makemigrations, le estás diciendo a Django que has hecho algunos cambios a sus modelos y que desea que los cambios se almacenarán como la migración. Las migraciones son cómo almacena Django cambios a sus modelos (y por tanto el esquema de base de datos) - son simplemente los archivos en el disco. Puedes leer la migración para su nuevo modelo si se quiere; que es el archivo polls/migrations/0001_initial.py . No te preocupes, no se espera para leerlos cada vez que Django hace uno, sino que están diseñados para ser humano editable en caso de que quiera ajustar manualmente cómo Django cambia las cosas. Ver SQL que generara Para ver el SQL que generara cuando cree la db, usar sqlmigrate. 4.6. Python 173 Apuntes Informatica Documentation, Publicación 1.0.0 Por ejemplo para ver 0001_initial.py 0002_auto_20140808_1242.py, solo poner el premer numero 0001 o 0002 Nota: Esto no genera la base de datos, solo muestra el SQL que generara cuando se haga migrate ./manage.py sqlmigrate polls 0001 Comprobar el modelo Esto solo comprueba si hay algun error en el modelo, pero no ejecuta nada. ./manage.py check Migrar las base de datos ./manage.py migrate El comando migrate toma todas las migraciones que no han sido aplicadas (pistas de Django cuáles se aplican mediante una tabla especial en su base de datos llamada django_migrations ) y les va en contra de su base de datos - en esencia, la sincronización de los cambios realizados en sus modelos con el esquema en la base de datos. Las migraciones son muy potentes y permiten cambiar tus modelos con el tiempo, a medida que desarrolle su proyecto, sin la necesidad de eliminar la base de datos o las tablas y hacer otros nuevos - que se especializa en la actualización de su base de datos en vivo, sin perder datos. Recordamos la guía de tres pasos para hacer cambios en el modelo: Cambiar los modelos (en models.py ). Ejecutar python manage.py makemigrations para crear migraciones de esos cambios Ejecutar python manage.py migrate para aplicar esos cambios a la base de datos. Limpiar migraciones Hacer primero un backup de la base de datos y un commit en Git MUY RECOMENDABLE Si se han echo muchos cambios en el modelo, sobre todo en las primeras etapas del proyecto, quizá sea bueno limpiar tanto las tabla django_migrations como el directorio app/migrations/ Eliminar la tabla django_migrations psql -U nombre_usuario nombre_db DROP TABLE IF EXISTS django_migrations; \q Eliminar los directorios app/migrations/, ir al directorio raíz del proyecto y ejecutar. find ./ -type d -name "migrations" -exec rm -rf {} \; Crear migraciones con makemigrations de las apps en el proyecto. Esta parte se ha de hacer por cada app. ./manage.py makemigrations app1 ./manage.py makemigrations app2 ./manage.py makemigrations appX 174 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Restablecer. ./manage.py migrate --fake-initial Municipios de España en la base de datos Fuentes: http://www.ine.es/jaxi/menu.do?type=pcaxis&path=%2Ft20%2Fe245%2Fcodmun%2F&file=inebase&L=0 https://iagolast.wordpress.com/2014/11/23/creando-un-select-ajax-de-provincias-y-municipios-espanoles/ Desde la pagina de http://www.ine.es se puede acceder Comunidades autónomas, provincias y municipios. El mas laborioso sin duda son los municipios, que son mas de 8000 en toda España. Las comunidades autónomas y provincias, las hago a mano, respetando los códigos como clave primaria. Para generar fixtures con Django, descargo el archivo Fichero con todas las provincias / Relación de municipios por provincia e isla Después ejecuto el siguiente código, que es una modificación de https://iagolast.wordpress.com Es necesario instalar pip install xlrd import xlrd import json def xls_to_json(filename): doc = xlrd.open_workbook(filename) sheet = doc.sheet_by_index(0) nrows = sheet.nrows municipios = [] pk = 0 if not is_valid(sheet): print("Error en {0}, el archivo tiene un formato inesperado.".format(filename)) for row in range(3, nrows): pk += 1 cod_mun = sheet.cell_value(row, 0) name_mun = sheet.cell_value(row, 3) municipios.append( {'model': 'poblaciones.municipio', 'pk': pk, 'fields': { 'name': name_mun, 'provincia': cod_mun }} ) with open('initial_data.json', 'wb') as fp: json_string = json.dumps(municipios, ensure_ascii=False).encode('utf8') fp.write(json_string) def is_valid(sheet): if str(sheet.cell_value(1, 0)) != "CPRO": print("Se esperaba CPRO y se tiene {0}".format(sheet.cell_value(2, 0))) return False if str(sheet.cell_value(1, 1)) != "CMUN": print("Se esperaba CMUN y se tiene {0}".format(sheet.cell_value(2, 1))) 4.6. Python 175 Apuntes Informatica Documentation, Publicación 1.0.0 return False if str(sheet.cell_value(1, 2)) != "DC": print("Se esperaba DC y se tiene {0}".format(sheet.cell_value(2, 2))) return False if str(sheet.cell_value(1, 3)) != "NOMBRE": print("Se esperaba NOMBRE y se tiene {0}".format(sheet.cell_value(2, 3))) return False return True xls_to_json('15codmun.xls') Después ejecutarlo con ./manage.py loaddata initial_data Nota: Es necesario tener una tabla con los campos name y provincia, donde provincia es la id de la tabla provincias class Municipio(models.Model): """Municipios.""" name = models.CharField(max_length=255) provincia = models.ForeignKey(Provincia, related_name='municipio_provincia') Obtener el anterior y el siguiente del objeto actual. Fuentes * https://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.get_next_by_FOO Ejemplo sencillo. La vista. class ArticleDetailView(generic.DetailView): """ Detalles de un articulo. """ template_name = 'blog/article_detail.html' model = Article context_object_name = 'article' def get_context_data(self, **kwargs): context = super(ArticleDetailView, self).get_context_data(**kwargs) # Obtener el anterior y siguiente articulo. try: context['article_previous'] = self.get_object().get_previous_by_create_at() except: context['article_previous'] = None try: context['article_next'] = self.get_object().get_next_by_create_at() except: context['article_next'] = None return context El template 176 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 <nav class="paginated"> <div class="row"> <div class="col-sm-6"> {% if article_previous %} <a href="{% url 'blog.article_detail' article_previous.slug %}"> <span class="glyphicon glyphicon-chevron-left"></span> {{ article_previous }} </a> {% endif %} </div> <div class="col-sm-6 text-right"> {% if article_next %} <a href="{% url 'blog.article_detail' article_next.slug %}"> {{ article_next }} <span class="glyphicon glyphicon-chevron-right"></span> </a> {% endif %} </div> </div> </nav> Pagination en ListView Fuentes https://djangosnippets.org/snippets/3023/ En views.py # myapp/views.py class MyModelListView(ListView): model = MyModel template_name = 'myapp/my_template.html' paginate_by = 10 En templates/my_template.html <!-- myapp/templates/my_template.html --> <nav> {% if is_paginated %} <ul class="pagination"> {% if page_obj.has_previous %} <li><a href="?page={{ page_obj.previous_page_number }}">&laquo;</a></li> {% endif %} {% for i in paginator.page_range %} <li {% if page_obj.number == i %} class="active" {% endif %}> <a href="?page={{i}}">{{ i }}</a> </li> {% endfor %} {% if page_obj.has_next %} <li><a href="?page={{ page_obj.next_page_number }}">&raquo;</a></li> {% endif %} </ul> 4.6. Python 177 Apuntes Informatica Documentation, Publicación 1.0.0 {% endif %} </nav> Pasar request en un Form o ModelForm desde generic.*View En el FormView o lo que sea *View crear metodo: class MyView(generic.FormView): def get_form_kwargs(self): kwargs = super(RegisterFormView, self).get_form_kwargs() kwargs['request'] = self.request return kwargs Ahora estara accesible en el Form desde el metodo __init__(). class MyForm(forms.ModelForm): def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) super(MyForm, self).__init__(*args, **kwargs) Problema con Error That port is already in use ps aux | grep -i manage kill -9 numero_pd Redis Cache Instalar Redis. pip install django-redis Configuracion en settings.py # Redis CACHE CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } } # Poner sessions con redis SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default" Restringir admin por IPs Fuentes 178 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 https://djangosnippets.org/snippets/2095/ — from django.conf import settings from django.core.urlresolvers import reverse, NoReverseMatch from django.http import Http404 class InternalUseOnlyMiddleware(object): """ Middleware to prevent access to the admin if the user IP isn't in the INTERNAL_IPS setting. """ def process_request(self, request): try: admin_index = reverse('admin:index') except NoReverseMatch: return if not request.path.startswith(admin_index): return remote_addr = request.META.get( 'HTTP_X_REAL_IP', request.META.get('REMOTE_ADDR', None) ) if remote_addr not in settings.INTERNAL_IPS and not settings.DEBUG: raise Http404 Otra opción, ver configuración de Nginx (Restringir una URL a IPs) Archivo settings a nivel de APP Hay varias formas para tener configuraciones a nivel de aplicación. # Opción 1 Crear archivo conf.py en la app from django.conf import settings MI_CONFIGURACION = getattr(settings, 'MI_CONFIGURACION', 'valor por defecto') Si no existe MI_CONFIGURACION en django.conf.settings le asigna un valor por defecto. # Opción 2 Crear archivo conf.py from django.conf import settings as default_settings class AppSettings(object): def __setattr__(self, key, value): if key != key.upper(): raise KeyError self.__dict__[key] = getattr(default_settings, key, value) settings = AppSettings() 4.6. Python 179 Apuntes Informatica Documentation, Publicación 1.0.0 settings.MI_CONFIGURACION = 'valor por defecto' AppSettings podría estar en utils/default_settings.py un archivo mas global a nivel de proyecto, por ejemplo en from django.conf import settings as default_settings class AppSettings(object): def __setattr__(self, key, value): if key != key.upper(): raise KeyError self.__dict__[key] = getattr(default_settings, key, value) settings = AppSettings() Y luego a nivel de aplicación en el archivo conf.py from utils.default_settings import settings settings.MI_CONFIGURACION = 'Mi valor por defecto' En todos los casos, para usarlo desde un archivo *.py from .conf import settings as myapp_settings print(myapp_settings.MI_CONFIGURACION) Si MI_CONFIGURACION tiene un valor en settings.py (archivo de configuración por defecto de Django) devolverá el valor de settings.MI_CONFIGURACION, en caso contrario, conf.MI_CONFIGURACION Union de QuerySets Fuentes http://stackoverflow.com/questions/431628/how-to-combine-2-or-more-querysets-in-a-django-view http://stackoverflow.com/questions/15596497/django-multiple-queryset-combine-into-a-pagination Obtener las consultas. c1 = MyModel1.objects.all() c2 = MyModel2.objects.all() c3 = MyModel3.objects.all() Unirlos con chain: from itertools import chain result_list = list(chain(c1, c2, c3)) # Si se quiere ordenar por algun campo. result_list = sorted( chain(c1, c1, c3), key=attrgetter('create_at') ) 180 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Con el operados de union | (siguiendo con c1, c2 y c3) result_list c1 | c2 | c3 El “problema” es que han ser del mismo modelo. En el comentario tambien habla de QuerySetChain en Validación campo de un modelo # my_app/validators.py from django.core.exceptions import ValidationError def titulo_validation(value): if not len(value) > 4: raise ValidationError('Minimo 4 caracteres') # my_app/models.py from django.db import models from .validators import titulo_validation class Articulo(models.Model): titulo = models.CharField(max_length=200, validators=[titulo_validation]) #.... Tambien es posible hacerlo desde un ModelForm # my_app/forms.py from django import forms from .models import Articulo from .validators import titulo_validation class MyForm(models.ModelForm): def __init__(self): super().__init__(*args, **kwargs) self.fields['titulo'].validators.append(titulo_validation) class Meta: model = Articulo 4.7 UML Categorias: 4.7. UML 181 Apuntes Informatica Documentation, Publicación 1.0.0 4.7.1 Relacion composicion agregacion Fuentes http://arodm.blogspot.com/2008/09/uml-relaciones-compocicion-agregacion.html Nota: Para ver los diagramas, pinchar en Fuentes Trabajando con los miembros de mi team de desarrollo me di cuenta que a los programadores le costaba interpretar los Diagramas de Clases que el analista realizaba. O existían interpretaciones ambiguas de lo que el realizaba, perdiendo asi la principal funcionalidad del lenguaje UML. Especialmente en cuanto a las relaciones que existían entre las clases. Por eso me dispuse a realizar este pequeño documento, donde voy a tratar de explicar que significa cada relación, en mis palabras, y como se traduce esto a código. Asociación Es generalmente, una relación estructural entre clases, es decir, que en el ejemplo, existe un atributo de la clase medio de transportes, que es del tipo Conductor. La navegabilidad nos muestra donde esta ubicado el atributo. Es decir cual es la clase que tiene contiene el atributo si ésta no lo mostrase. Agregación Es una relación que se derivó de la asociación, por ser igualmente estructural, es decir que contiene un atributo, que en todos los casos, será una colección, es decir un array, vector, etc, y además de ello la clase que contiene la colección debe tener un método que agregue los elementos a la colección. También se puede leer como que un medio de transporte tiene varias ruedas. Nos esta diciendo que los objetos rueda forman parte del objeto medio de transporte. Pero, su ciclo de vida no esta atado al del objeto medio de transporte. Es decir si el automóvil se destruye las ruedas pueden seguir existiendo independientemente. Composición Al igual que en la agregación, es una relación estructural pero se le suma, que tiene un método de destrucción de los objetos. Y a diferencia de la asociación, el ciclo de vida del objeto area está relacionado con el del objeto ruta. Es decir que si la ruta de viaje se levanta, las áreas que surgían a partir de ella desaparecen. También se puede leer como que una ruta tiene varias áreas de cobertura. Mucho se ha discutido a cerca de las agregaciones y las composiciones, el debate es casi tan caliente como el de los include y extends de los casos de uso. Ya que algunos sostienen que los lenguajes orientados a objetos, tienen garbage collector, por lo que no necesitan métodos de destrucción de los objetos (relacionados a los ciclos de vida en la composición). Y que la programación es la misma para las composiciones y las agregaciones, y que la diferencia es meramente conceptual entre una y otras. Es mas existen varias interpretaciones, pero la expuesta es la cual yo me adhiero. 182 Capítulo 4. Programacion Apuntes Informatica Documentation, Publicación 1.0.0 Clase de Asociación Es una Clase que surge de una multiplicidad de muchos a muchos, y fue incorporada en UML para dar soporte a este caso. Se sacan los atributos de las clases involucradas y se los incorpora a una clase a parte. Al igual que las anteriores hace referencia a una relación estructural. En el ejemplo son los objetos viaje y ruta. Realización Es una relación de contrato con otra clase. Se la utiliza para implementar una interfaz. En lenguajes como java o php utilizamos la palabra reservada implements public class Viaje implements InterfaceA{...} Generalmente cuando no estamos seguros si algo es una interfaz o una clase abstracta, por que dibujaron los tag que hacen referencias a las interfaces, debemos ver la relación para saber. Generalización Es una relación de herencia. Se puede decir que es un relación es un tipo de. En nuestro ejemplo: “un auto es un tipo de Medio de transporte”. Es entre una clase hija y su clase madre. En la codificación podemos encontrar la palabra “extends” que hace referencia a esta relación. Además podemos encontrar palabras claves tales como this y super o self y parent. Para darnos cuenta que existe una relación de este tipo involucrada. public class Auto extends MedioDeTransporte{...} Dependencia Es una relación de uso, es decir que una clase utiliza a otra. Y si esta ultima se altera, la anterior se puede ver afectada. En código se suelen traducir principalmente como las clases donde se hace la instanciación de un objeto. En nuestro ejemplo la clase viaje realiza los new de los distintos objetos. En este momento puede que te preguntes como puede hacer un new de una clase abstracta, jeje. No realiza los new de la clase abstracta, si no de sus hijas. Seria algo así como MedioDeTransporte medio = new Auto(); También se sostiene que este tipo de relación hace referencias, a los parámetros que se pasan en un método, bajo este concepto, en java, podría ser algo así como: public void crearViaje(MedioDeTransporte medio) {} Por ultimo también se sostiene que podemos codificar esta relación realizando un return del tipo de dato en algún método. Bueno espero haber limpiado algunas dudas, hay mucho para discutir sobre el asunto. 4.7. UML 183 Apuntes Informatica Documentation, Publicación 1.0.0 184 Capítulo 4. Programacion CAPÍTULO 5 Windows Contents 5.1 Compartir directorios en VirtualBox Todo esto esta pensado para tener como host a windows virtualizando linux. Con linux/linux, todo esto no es necesario. 5.1.1 En windows, virtualbox (Host) Entrar en la configuración de la maquina virtual de VB y en la opciones de red pongo Adaptador puente En carpetas compartidas -> Carpetas de la máquina: Ruta carpeta: Ruta de la carpeta host Nombre carpeta: Nombre para identificarlo Sólo lectura: Desactivado Automontar: Activado Hacer permanente: Activado 5.1.2 Linux, maquina virtualizada (Guest) Requisitos Tener instalado virtualbox-guest-additions. Tener uno o varios usuarios creados. Añadir usuario/s al grupo vboxsf sudo usermod -a -G vboxsf snicoper reiniciar Las carpetas se automontan en (ubuntu) /media/sf_Nombre_carpeta Ahora si se quiere tener mas mano: 185 Apuntes Informatica Documentation, Publicación 1.0.0 ln -s /media/sf_Nombre_carpeta ~/nombre_carpeta 5.1.3 Con Samba De esta manera, se puede compartir, por ejemplo, todo el directorio de un usuario linux y acceder desde windows, como la carpeta entera de home. Ubuntu sudo apt install samba sudo smbpasswd -a snicoper sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.copia vim /etc/samba/smb.conf # Añadir al final [home_snicoper] path = /home/snicoper available = yes valid users = snicoper read only = no browseable = yes public = yes writable = yes # Reiniciar samba sudo restart smbd Fedora/Centos yum install samba samba-client samba-common -y /usr/bin/smbpasswd -a snicoper Editar smb.conf cp /etc/samba/smb.conf /etc/samba/smb.conf.copia vim /etc/samba/smb.conf # Linea 66 añadir: unix charset = UTF-8 # Linea 89 modificar: workgroup = WORKGROUP # Linea 95 descomentar y modificar: hosts allow = 127. 192.168.1. # Linea 125 añadir: map to guest = Bad User 186 Capítulo 5. Windows Apuntes Informatica Documentation, Publicación 1.0.0 # Añadir al final: [home_snicoper] path = /home/snicoper writable = yes browsable = yes guest ok = yes guest only = yes create mode = 0777 directory mode = 0777 SELinux setsebool -P samba_enable_home_dirs on Firewall firewall-cmd --permanent --zone=public --add-service=samba firewall-cmd --reload Iniciar y añadir como servicio systemctl start smb.service systemctl enable smb.service Windows Ir a This PC y añadir Map network drive, seguir los pasos. Drive: Elegir una letra Folder: \\192.168.1.2\snicoper 5.2 Eliminar un Servicio sc delete nombre_servicio 5.3 Nginx y PHP en Windows Descargar php Non Thread Safe Descargar nginx Descargar NSSM (Non-Sucking Service Manager) Descomprimir los 3 archivos y re nombrarlos son la versión (opcional), mover a C:\ (opcional), quedando de la siguiente manera: C:\nginx C:\php C:\nssm Añadir al path C:\nginx;C:\php;C:\nssm\win64; 5.2. Eliminar un Servicio 187 Apuntes Informatica Documentation, Publicación 1.0.0 5.3.1 Configuración de Nginx Editar C:\nginx\conf\nginx.conf http { # ... # Añadir al final de http { la siguiente linea include C:/nginx/conf/vhosts/*.conf; } Crear directorio C:/nginx/conf/vhosts, es donde estaran los host virtuales de nginx. Crear en el directorio de usuario ~/Projects/www Crear C:/nginx/conf/vhosts/snicoper.dev.conf y añadir: server { listen 80; server_name snicoper.dev; access_log logs/snicoper.dev-access.log; error_log logs/snicoper.dev-error.log; root C:/Users/snicoper/Projects/www; location / { index index.html index.htm index.php; } location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ { access_log off; log_not_found off; expires 360d; } # Si quiero que se vean los archivos y directorios cambiar a on autoindex on; location ~ \.php$ fastcgi_pass fastcgi_index fastcgi_param } { 127.0.0.1:9000; index.php; SCRIPT_FILENAME C:/Users/snicoper/Projects/www$fastcgi_script_name; } 5.3.2 Configuración de php Entrar en C:\php copiar/pegar php.ini-development y renombrarlo a php.ini Editar C:\php\php.ini ; Linea 736, descomentar extension_dir = "ext" ; Linea 927, descomentar y añadir zona horaria date.timezone = Europe/Madrid ; A partir de la linea 878, descomentar las extensiones necesarias 188 Capítulo 5. Windows Apuntes Informatica Documentation, Publicación 1.0.0 5.3.3 Configuración de Nssm Entrar en una terminal (Símbolo del sistema) como administrador: nssm install nginxd # Path: C:\nginx\nginx.exe # Startup directory: C:\nginx # Pulsar 'Edit service' nssm install phpcgid # Path: C:\php\php-cgi.exe # Startup directory: C:\php # Arguments: -b 127.0.0.1:9000 # Pulsar 'Edit service' Iniciar servicios nssm start nginxd nssm start phpcgid Para ver el resto de comandos escribir solo nssm, al iniciar se los servicios se iniciaran solos. Para probar crear archivo ~/Projects/www/test.php añadiendo <?php phpinfo(); Nota: Es necesario añadir al archivo host 127.0.0.1 snicoper.dev 5.3.4 XDebug Abrimos la terminal y ejecutamos: php -i > phpini.txt Abrimos el archivo phpini.txt y copiamos su contenido. Ahora vamos a Xdebug ,lo pegamos en el textarea y le damos al boton Analyse my phpinfo() output. Nos mostrara que descarga tenemos que hacer. Descargar el archivo y renombrar a php_xdebug.dll, después, copiar el archivo en C:\php\ext, por ultimo editar el archivo C:\php\php.ini y añadir al final: zend_extension = C:\php\ext\php_xdebug.dll 5.3. Nginx y PHP en Windows 189 Apuntes Informatica Documentation, Publicación 1.0.0 5.3.5 Composer Descargar composer y seguir las instrucciones del instalador, la única nota es que en el php.ini se ha de descomentar la linea extension=php_openssl.dll antes de comenzar la instalación. 5.4 Instalación de PostgreSQL Windows 5.4.1 Fuentes http://www.postgresql.org/ http://www.petrikainulainen.net/programming/tips-and-tricks/installing-postgresql-9-1-to-windows-7-fromthe-binary-zip-distribution/ http://www.pgadmin.org/ Nota: Para una instalación rápida, descargar el instalador y solo añadirlo al PATH, me creo la menera del .zip por pura curiosidad. La versión probada es 9.3.4, cambiar según versión. Descargar el archivo .zip Crear carpeta C:\Postgresql Descomprimir carpeta en C:\Postgresql Renombrar C:\Postgresql\pgsql a C:\Postgresql\9.3.4 Crear dentro de C:\Postgresql\9.3.4 dos directorios data log 5.4.2 Añadir el PATH C:\Postgresql\9.3.4\bin; 5.4.3 CMD Inicializar data initdb -U postgres -A password -E utf8 -W -D C:\Postgresql\9.3.4\data Iniciar pg_ctl -D "C:/Postgresql/9.3.4/data" -l "C:/Postgresql/9.3.4/log/pgsql.log" start 190 Capítulo 5. Windows Apuntes Informatica Documentation, Publicación 1.0.0 Parar pg_ctl -D “C:/Postgresql/9.3.4/data” -l “C:/Postgresql/9.3.4/log/pgsql.log” stop 5.4.4 Añadir como Servicio pg_ctl.exe register -N Postgresql -U "NT AUTHORITY\NetworkService" -D "C:/Postgresql/9.3.4/data" -w 5.4.5 Descargar e instalar pgadmin http://www.pgadmin.org/ 5.4.6 Configurar Abrir C:\Postgresql\9.3.4\data\postgresql.conf # Descomentar listen_addresses = 'localhost' port = 5432 Crear base de datos practicas y usuario snicoper psql -U postgres CREATE USER snicoper WITH PASSWORD '123456' NOCREATEDB NOCREATEUSER; CREATE DATABASE practicas WITH OWNER = snicoper; Nota: Para evitar el mensaje en cmd ADVERTENCIA: El código de página de la consola (850) difiere del código de página de Windows (1252). [...] En CMD poner /c chcp 1252 5.5 Instalación Python en Windows 5.5.1 Variables de entorno C:\Python35\;C:\Python35\Scripts\; 5.5.2 Virtualenvwrapper pip install virtualenvwrapper-win 5.5. Instalación Python en Windows 191 Apuntes Informatica Documentation, Publicación 1.0.0 Por defecto usara ~/Envs para los entornos virtuales, si se quiere cambiar el directorio, añadir la variable de entorno WORKON_HOME indicandole la nueva ruta. Añadir la variable de entorno WORKON_HOME con el valor %USERPROFILE %\virtualenvs Pysopg2 version 2.6 x64 (default) easy_install http://www.stickpeople.com/projects/python/win-psycopg/2.6.2/psycopg2-2.6.2.wi 5.6 Instalar Cygwin 5.6.1 Fuentes http://www.cygwin.com/ Descargar el instalador e instalar. La primera vez que lo instalo, lo instalo sin elegir nada, cuando a acabado la primera instalación, lo vuelvo a ejecutar y selecciono los paquetes a instalar. openssh wget ca-certificates curl tree Añadir al path C:\cygwin64\bin; Instalar apt-cyg wget rawgit.com/transcode-open/apt-cyg/master/apt-cyg install apt-cyg /bin Modificar C:\cygwin64\home\snicoper\.bashrc alias alias alias alias alias ll='ls -lF' la='ls -a' lla='ll -a' statc='stat -c %a' ccat='pygmentize -g' # Git function git_branch { git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /' } PS1='\[\e[0;32m\]\u@\[\e[m\]\[\e[0;32m\]\h\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\n\[\033[0;32m\ 192 Capítulo 5. Windows